| /* Copyright (c) 1999, 2000 by Kevin Forchione. All Rights Reserved. */ | |
| /* | |
| * TADS ADV.T/STD.T LIBRARY EXTENSION | |
| * SMARTLIST.T | |
| * version 1.0 | |
| * | |
| * smartlist.t provides an enhancement of the standard ADV.T listing | |
| * functions. These enhancements include: | |
| * | |
| * smartlist | |
| * Useful in debugging, smartlist displays objects of various | |
| * datatypes. | |
| * listcont | |
| * listcontcont | |
| * The use of lists or objects as function parameters | |
| * showcontcont | |
| * itemXcnt | |
| * listXcont | |
| * Display of Actors in nestedrooms | |
| * listfixedcont | |
| * Display of fixeditems in room listings when Actor is inside | |
| * of enterable class objects. | |
| * | |
| *---------------------------------------------------------------------- | |
| * REQUIREMENTS | |
| * | |
| * + HTML TADS 2.2.6 or later | |
| * + Requires ADV.T and STD.T | |
| * + Should be #included after ADV.T and STD.T. | |
| * | |
| *---------------------------------------------------------------------- | |
| * IMPORTANT LIBRARY INTERFACE AND MODIFICATION | |
| * | |
| * This module modifies the functioning of the following ADV.T | |
| * listing functions: | |
| * | |
| * + listcont() | |
| * + listcontcont() | |
| * + showcontcont() | |
| * | |
| *---------------------------------------------------------------------- | |
| * 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 | |
| * | |
| * 12-May-99: Creation. | |
| */ | |
| #define __SMARTLIST_MODULE_ | |
| smartlist: function; | |
| listfixedcont: function; | |
| itemXcnt: function; | |
| listXcont: function; | |
| /* | |
| * smartlist: function( list, origlen ) | |
| * | |
| * This is a recursive function that is useful for displaying | |
| * information in nested lists. It will separate each item by | |
| * a space, and separate sublists with '[ ... ]' indicators. | |
| * | |
| * Method is passed a list and the length of the list, which is | |
| * used to determine spacing. | |
| */ | |
| smartlist: function( list, origlen ) | |
| { | |
| local o; | |
| if ( list = nil or length( list ) = 0 ) return; | |
| if ( origlen = 2 ) | |
| { | |
| if ( length( list ) < origlen ) | |
| " and "; | |
| } | |
| else if ( origlen > 2 ) | |
| { | |
| if ( length( list ) = 1 ) | |
| ", and "; | |
| else if ( length( list ) < origlen ) | |
| ", "; | |
| } | |
| o := car( list ); | |
| switch( datatype( o ) ) | |
| { | |
| case 1: // number | |
| say( o ); | |
| break; | |
| case 2: // object | |
| if ( proptype( o, &sdesc ) <> 5 ) | |
| o.sdesc; | |
| else | |
| "(unnamed_object)"; | |
| break; | |
| case 3: // string | |
| say( o ); | |
| break; | |
| case 5: // nil | |
| "(nil)"; | |
| break; | |
| case 7: // list | |
| "["; | |
| smartlist( o, length( o ) ); | |
| "]"; | |
| break; | |
| case 8: // true; | |
| "(true)"; | |
| break; | |
| case 10: // function pointer | |
| "(function_pointer)"; | |
| break; | |
| case 13: // property pointer | |
| "(property_pointer)"; | |
| break; | |
| default: | |
| } | |
| list := cdr( list ); | |
| smartlist( list, origlen ); | |
| } | |
| /* | |
| * listfixedcont: function(obj) | |
| * | |
| * This function is similar to listcont(obj). | |
| * | |
| * This function displays the fixeditem / actor contents of an | |
| * object/list, separated by commas. The thedesc properties of the | |
| * contents are used. It is up to the caller to provide the | |
| * introduction to the list (usually something to the effect of "The | |
| * box contains" is displayed before calling listXfixedcont) and | |
| * finishing the sentence (usually by displaying a period). An object | |
| * is listed only if its isactor or isfixed property is true. If there | |
| * are multiple indistinguishable items in the list, the items are | |
| * listed only once (with the number of the items). | |
| */ | |
| listfixedcont: function(obj) | |
| { | |
| local i, count, tot, list, cur, disptot := 0, prefix_count; | |
| if (datatype(obj) = 2) | |
| list := obj.contents; | |
| else | |
| list := obj; | |
| tot := length(list); | |
| count := 0; | |
| for (i := 1; i <= tot; ++i) | |
| { | |
| if ( list[i].isactor or list[i].isfixed ) | |
| disptot++; | |
| } | |
| for (i := 1 ; i <= tot ; ++i) | |
| { | |
| cur := list[i]; | |
| if (cur.isactor or cur.isfixed) | |
| { | |
| /* presume there is only one such object */ | |
| prefix_count := 1; | |
| /* | |
| * if this is one of more than one equivalent items, list it | |
| * only if it's the first one, and show the number of such | |
| * items along with the first one | |
| */ | |
| if (cur.isEquivalent) | |
| { | |
| local before, after; | |
| local j; | |
| local sc; | |
| sc := firstsc(cur); | |
| for (before := after := 0, j := 1 ; j <= tot ; ++j) | |
| { | |
| if (isIndistinguishable(cur, list[j])) | |
| { | |
| if (j < i) | |
| { | |
| /* | |
| * note that objects precede this one, and | |
| * then look no further, since we're just | |
| * going to skip this item anyway | |
| */ | |
| ++before; | |
| break; | |
| } | |
| else | |
| ++after; | |
| } | |
| } | |
| /* | |
| * if there are multiple such objects, and this is the | |
| * first such object, list it with the count prefixed; | |
| * if there are multiple and this isn't the first one, | |
| * skip it; otherwise, go on as normal | |
| */ | |
| if (before = 0) | |
| prefix_count := after; | |
| else | |
| continue; | |
| } | |
| if (count > 0) | |
| { | |
| if (count+1 < disptot) | |
| ", "; | |
| else if (count = 1) | |
| " and "; | |
| else | |
| ", and "; | |
| } | |
| /* list the object, along with the number of such items */ | |
| if (prefix_count = 1) | |
| cur.adesc; | |
| else | |
| { | |
| sayPrefixCount(prefix_count); " "; | |
| cur.pluraldesc; | |
| } | |
| /* show any additional information about the item */ | |
| if (cur.isworn) | |
| " (being worn)"; | |
| if (cur.islamp and cur.islit) | |
| " (providing light)"; | |
| count := count + 1; | |
| } | |
| } | |
| } | |
| /* | |
| * listcont: function(obj) | |
| * | |
| * This function performs exactly as ADV.T listcont(obj). The | |
| * only difference is that it accepts a list or an object. | |
| * | |
| * This function displays the contents of an object/list, separated | |
| * by commas. The thedesc properties of the contents are used. | |
| * It is up to the caller to provide the introduction to the list | |
| * (usually something to the effect of "The box contains" is | |
| * displayed before calling listXcont) and finishing the | |
| * sentence (usually by displaying a period). An object is listed | |
| * only if its isListed property is true. If there are | |
| * multiple indistinguishable items in the list, the items are | |
| * listed only once (with the number of the items). | |
| */ | |
| replace listcont: function(obj) | |
| { | |
| local i, count, tot, list, cur, disptot, prefix_count; | |
| if (datatype(obj) = 2 ) | |
| list := obj.contents; | |
| else | |
| list := obj; | |
| tot := length(list); | |
| count := 0; | |
| disptot := itemcnt(list); | |
| for (i := 1 ; i <= tot ; ++i) | |
| { | |
| cur := list[i]; | |
| if (cur.isListed) | |
| { | |
| /* presume there is only one such object */ | |
| prefix_count := 1; | |
| /* | |
| * if this is one of more than one equivalent items, list it | |
| * only if it's the first one, and show the number of such | |
| * items along with the first one | |
| */ | |
| if (cur.isEquivalent) | |
| { | |
| local before, after; | |
| local j; | |
| local sc; | |
| sc := firstsc(cur); | |
| for (before := after := 0, j := 1 ; j <= tot ; ++j) | |
| { | |
| if (isIndistinguishable(cur, list[j])) | |
| { | |
| if (j < i) | |
| { | |
| /* | |
| * note that objects precede this one, and | |
| * then look no further, since we're just | |
| * going to skip this item anyway | |
| */ | |
| ++before; | |
| break; | |
| } | |
| else | |
| ++after; | |
| } | |
| } | |
| /* | |
| * if there are multiple such objects, and this is the | |
| * first such object, list it with the count prefixed; | |
| * if there are multiple and this isn't the first one, | |
| * skip it; otherwise, go on as normal | |
| */ | |
| if (before = 0) | |
| prefix_count := after; | |
| else | |
| continue; | |
| } | |
| if (count > 0) | |
| { | |
| if (count+1 < disptot) | |
| ", "; | |
| else if (count = 1) | |
| " and "; | |
| else | |
| ", and "; | |
| } | |
| /* list the object, along with the number of such items */ | |
| if (prefix_count = 1) | |
| cur.adesc; | |
| else | |
| { | |
| sayPrefixCount(prefix_count); " "; | |
| cur.pluraldesc; | |
| } | |
| /* show any additional information about the item */ | |
| if (cur.isworn) | |
| " (being worn)"; | |
| if (cur.islamp and cur.islit) | |
| " (providing light)"; | |
| count := count + 1; | |
| } | |
| } | |
| } | |
| /* | |
| * listcontcont: function(obj) | |
| * | |
| * This function performs exactly as ADV.T listcontcont(obj). The | |
| * only difference is that it accepts a list or an object. | |
| * | |
| * This function lists the contents of the contents of an | |
| * object/list. It displays full sentences, so no introductory or | |
| * closing text is required. Any item in the contents list of the | |
| * object obj whose contentsVisible property is true has | |
| * its contents listed. An Object whose isqcontainer or | |
| * isqsurface property is true will not have its | |
| * contents listed. | |
| */ | |
| replace listcontcont: function(obj) | |
| { | |
| local list, i, tot; | |
| if (datatype(obj) = 2) | |
| list := obj.contents; | |
| else | |
| list := obj; | |
| tot := length(list); | |
| i := 1; | |
| while (i <= tot) | |
| { | |
| showcontcont(list[i]); | |
| i := i + 1; | |
| } | |
| } | |
| /*------------------------------------------------------------------------------ | |
| * FUNCTIONS USED TO DISPLAY ACTORS IN NESTED ROOMS | |
| *----------------------------------------------------------------------------*/ | |
| /* | |
| * This function has been modified to use the new itemXcnt() and | |
| * listXcont() functions, which take into account items and Actors. | |
| */ | |
| replace showcontcont: function(obj) | |
| { | |
| if (itemXcnt(obj.contents)) | |
| { | |
| if (obj.issurface) | |
| { | |
| if (not obj.isqsurface) | |
| { | |
| "Sitting on "; obj.thedesc;" is "; listXcont(obj); | |
| ". "; | |
| } | |
| } | |
| else if (obj.contentsVisible and not obj.isqcontainer) | |
| { | |
| caps(); | |
| obj.thedesc; " seem"; | |
| if (!obj.isThem) "s"; | |
| " to contain "; | |
| listXcont(obj); | |
| ". "; | |
| } | |
| } | |
| if (obj.contentsVisible and not obj.isqcontainer) | |
| listfixedcontcont(obj); | |
| } | |
| /* | |
| * itemXcnt: function( list ) | |
| * | |
| * This functions exactly as itemcnt() does, except that it includes | |
| * Actors into its totals. Any object that has .isactor = true will | |
| * be included. | |
| */ | |
| itemXcnt: function(list) | |
| { | |
| local cnt, tot, i, obj, j; | |
| tot := length(list); | |
| for (i := 1, cnt := 0 ; i <= tot ; ++i) | |
| { | |
| /* only consider this item if it's to be listed */ | |
| obj := list[i]; | |
| if (obj.isListed or obj.isactor) | |
| { | |
| /* | |
| * see if there are other equivalent items later in the | |
| * list - if so, don't count it (this ensures that each such | |
| * item is counted only once, since only the last such item | |
| * in the list will be counted) | |
| */ | |
| if (obj.isEquivalent) | |
| { | |
| local sc; | |
| sc := firstsc(obj); | |
| for (j := i + 1 ; j <= tot ; ++j) | |
| { | |
| if (isIndistinguishable(obj, list[j])) | |
| goto skip_this_item; | |
| } | |
| } | |
| /* count this item */ | |
| ++cnt; | |
| skip_this_item: ; | |
| } | |
| } | |
| return cnt; | |
| } | |
| /* | |
| * listXcont: function( obj ) | |
| * | |
| * This functions exactly as listcont(), except that it takes Actors into | |
| * account. We don't replace listcont(), however, because it's only when | |
| * actors are inside nested rooms that we want to list them in this manner. | |
| * When they are inside the player's location | |
| * we use the normal method. | |
| */ | |
| listXcont: function(obj) | |
| { | |
| local i, count, tot, list, cur, disptot, prefix_count; | |
| if (datatype(obj) = 2) | |
| list := obj.contents; | |
| else | |
| list := obj; | |
| tot := length(list); | |
| count := 0; | |
| disptot := itemXcnt(list); | |
| for (i := 1 ; i <= tot ; ++i) | |
| { | |
| cur := list[i]; | |
| if (cur.isListed or cur.isactor) | |
| { | |
| /* presume there is only one such object */ | |
| prefix_count := 1; | |
| /* | |
| * if this is one of more than one equivalent items, list it | |
| * only if it's the first one, and show the number of such | |
| * items along with the first one | |
| */ | |
| if (cur.isEquivalent) | |
| { | |
| local before, after; | |
| local j; | |
| local sc; | |
| sc := firstsc(cur); | |
| for (before := after := 0, j := 1 ; j <= tot ; ++j) | |
| { | |
| if (isIndistinguishable(cur, list[j])) | |
| { | |
| if (j < i) | |
| { | |
| /* | |
| * note that objects precede this one, and | |
| * then look no further, since we're just | |
| * going to skip this item anyway | |
| */ | |
| ++before; | |
| break; | |
| } | |
| else | |
| ++after; | |
| } | |
| } | |
| /* | |
| * if there are multiple such objects, and this is the | |
| * first such object, list it with the count prefixed; | |
| * if there are multiple and this isn't the first one, | |
| * skip it; otherwise, go on as normal | |
| */ | |
| if (before = 0) | |
| prefix_count := after; | |
| else | |
| continue; | |
| } | |
| if (count > 0) | |
| { | |
| if (count+1 < disptot) | |
| ", "; | |
| else if (count = 1) | |
| " and "; | |
| else | |
| ", and "; | |
| } | |
| /* list the object, along with the number of such items */ | |
| if (prefix_count = 1) | |
| cur.adesc; | |
| else | |
| { | |
| sayPrefixCount(prefix_count); " "; | |
| cur.pluraldesc; | |
| } | |
| /* show any additional information about the item */ | |
| if (cur.isworn) | |
| " (being worn)"; | |
| if (cur.islamp and cur.islit) | |
| " (providing light)"; | |
| count := count + 1; | |
| } | |
| } | |
| } | |
Xet Storage Details
- Size:
- 16.4 kB
- Xet hash:
- 64b67b6ccae234e75f51084df5c03b1d9d311b3bf2d8644c532d35b9052a45b2
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.