#charset "us-ascii"
#include "advlite.h"
/*
* ***************************************************************************
* lister.t
*
* This module forms part of the adv3Lite library (c) 2012-13 Eric Eve, and is
* substantially borrowed from the Mercury library (c) 2012 Michael J.
* Roberts.
*/
/*
* Lister is the class that displays lists of objects. This is used in
* room descriptions, inventory lists, and EXAMINE descriptions of
* objects (to show the examined object's contents).
*
* Showing a listing is basically a function call. The reason we make a
* whole class out of it is that we provide a number of options, and a
* class is a convenient way to specify options. The options are simply
* defined as properties of a lister object, so to create a certain kind
* of list, you just set up a Lister instance with the desired options.
* We provide pre-defined Lister objects for the common library listing
* types, but games can create their own custom list types by creating
* their own Lister objects for different sets of options.
*/
class Lister: object
/*
* Show a list of objects. 'lst' is the list of objects to show;
* 'paraCnt' is the number of paragraph-style descriptions that we've
* already shown as part of this description.
*
* Note that many specific listers replaced the 'paraCnt' parameter with a
* more useful 'parent' parameter, containing the identity of the object
* whose contents are being listed.
*/
show(lst, paraCnt, paraBrk = true)
{
/* get the subset that passes our 'listed' test */
lst = lst.subset({ o: listed(o) });
/* if we have any items, show them */
if (lst.length() > 0)
{
/* sort into listing order */
lst = lst.sort(SortAsc, { a, b: listOrder(a) - listOrder(b) });
/*
* The list is plural if it has multiple items, or a single item
* that has plural usage.
*/
local pl = (lst.length() > 1 || lst[1].plural);
/* Show the list prefix */
showListPrefix(lst, pl, paraCnt);
/* show the items */
showList(lst, pl, paraCnt);
/* Show the list suffix. */
showListSuffix(lst, pl, paraCnt);
/* add a paragraph break at the end, if it's requested */
if(paraBrk)
"<.p>";
}
else
showListEmpty(paraCnt);
}
showListPrefix(lst, pl, paraCnt) { }
showListSuffix(lst, pl, paraCnt) { }
showListEmpty(paraCnt) { }
/*
* Should 'obj' be listed in this list? Returns true if so, nil if not.
* By default, we list any object whose 'listed' property is true.
*/
listed(obj) { return obj.listed; }
/*
* Get an item's sorting order. This returns an integer that gives the
* relative position in the list; we order the list in ascending order of
* this value. By default, we return the 'listOrder' property of the
* object.
*/
listOrder(obj) { return obj.listOrder; }
/*
* Return a string containing what this lister would display, minus the
* terminating paragraph break.
*/
buildList(lst)
{
local str = gOutStream.captureOutput({: show(lst, 0, nil) });
return str;
}
;
/*
* An Item Lister is a lister used for listing physical items. Notice that
* most of the specifics of the listers defined below are language-specific,
* and so are defined in the language-specific part of the library (e.g. in
* english.t).
*/
class ItemLister: Lister
/*
* Show a list of objects. 'lst' is the list of objects to show; 'parent'
* parameter is the object whose contents are being listed, 'paraBrk'
* defines whether or not we want a paragraph break after the list.
*/
show(lst, parent, paraBrk = true)
{
/* Carry out the inherited handling */
inherited(lst, parent, paraBrk);
/* Note that every item in our list has been mentioned and seen */
foreach(local cur in lst)
{
cur.mentioned = true;
cur.noteSeen();
}
}
/*
* The property on a Thing-derived container to test whether its contents
* should be listed when listing with this lister
*/
contentsListedProp = &contentsListed
/*
* Flag, so we want to list contents of contents when using this lister;
* by default we do.
*/
listRecursively = true
;
/*
* lookLister displays a list of miscellaneous objects in a room description.
*/
lookLister: ItemLister
/* is the object listed in a LOOK AROUND description? */
listed(obj) { return obj.lookListed && !obj.isHidden; }
;
/*
* lookContentsLister is used to display a list of the contents of objects in
* a room description.
*/
lookContentsLister: ItemLister
/* is the object listed in a LOOK AROUND description? */
listed(obj) { return obj.lookListed && !obj.isHidden; }
contentsListedProp = &contentsListedInLook
;
/*
* inventoryLister displays an inventory listing in WIDE format.
*/
inventoryLister: ItemLister
/* is the object listed in an inventory list? */
listed(obj) { return obj.inventoryListed && !obj.isHidden; }
;
/* wornLister displays a list of items being worn. */
wornLister: ItemLister
/* is the object listed in an inventory list? */
listed(obj) { return obj.inventoryListed && !obj.isHidden; }
;
/*
* inventoryTallLister for displaying an inventory list in TALL format.
*/
inventoryTallLister: ItemLister
/* is the object listed in an inventory list? */
listed(obj) { return obj.inventoryListed && !obj.isHidden; }
showList(lst, parent, paraBrk = true)
{
/* list the inventory using the inventory tall format. */
showContentsTall(lst, parent, paraBrk);
/* Ensure the indentation level is reset to zero once we've finished listing */
indentLevel = 1;
}
/*
* List the player's inventory in tall format, i.e., as a columnar list with each item on a
* new line. This method may call itself recursively to list subcontents (such as the visible
* contents of any containers in the player character's inventory).
*/
showContentsTall(lst, parent, paraBrk = true)
{
foreach(local cur in lst)
{
/* Carry out the indenting for sublisting contents */
for(local i in 1..indentLevel)
"\t";
/* Display the appropriate name for the listed item */
say(listName(cur));
/* Move to a new line */
"\n";
/* Note that every item in our list has been mentioned and seen */
cur.mentioned = true;
cur.noteSeen();
/*
* If we want to list recursively and we haven't yet reached out maximum indentation
* (i.e., nesting) level, then build a list of subcontents and then display it.
*/
if(listRecursively && indentLevel < maxIndentLevel)
{
/*
* Get a list of the current item's listable contents. If we can't see in this is
* an empty list.
*/
local subList = (cur.contType == In && !cur.canSeeIn)
? [] : cur.contents.subset({o: listed(o) });
/* If we have an open or transparent subcontainer, add its contents. */
if(cur.remapIn && cur.remapIn.canSeeIn)
subList += cur.remapIn.contents.subset({o: listed(o) });
/* If we have a subsurface, add its contents. */
if(cur.remapOn)
subList += cur.remapOn.contents.subset({o: listed(o) });
/*
* If this list isn't empty, then display this list of subcontents as a column of
* items indented under their containing item.
*/
if(subList.length > 0)
{
/* increment the indentation level. */
indentLevel++;
/* sort the list of subcontents in ascending order of their listOrder property */
subList = subList.sort(true, {x, y: y.listOrder - x.listOrder});
/* call this method recursively to list the subcontents. */
showContentsTall(subList, cur, paraBrk);
/* decrement the indentation level once we've finished listing. */
indentLevel-- ;
}
}
}
}
/*
* A version of the listName method that doesn't list an items contents in parenthesis after
* its name, which would be inappropriate to the tall inventory format.
*/
listName(o)
{
/*
* When we're doing a tall inventory listing we don't want to list sucontents after the
* name of each item, so we store the current value of showSubListing, then set
* showSublisting to nil before carrying out the inherited handling, and then finally
* restore the original value of ShowSubListing.
*/
local ssl = showSubListing;
showSubListing = nil;
local lnam = inherited(o);
showSubListing = ssl;
return lnam;
}
/* The current indentation level for listing subcontents recursively */
indentLevel = 1
/* The maximum level of indentation we want to allow for listed nested subcontents. */
maxIndentLevel = 5
/*
* The property on a Thing-derived container to test whether its contents
* should be listed when listing with this lister
*/
contentsListedProp = &contentsListed
/*
* Flag, so we want to list contents of contents when using this lister;
* by default we do.
*/
listRecursively = true
showListPrefix(lst, pl, paraCnt) { DMsg(list tall prefix, '\n{I} {am} carrying:\n '); }
showListSuffix(lst, pl, paraCnt) { }
showListEmpty(paraCnt) { DMsg(list tall empty, '\n{I} {am} empty-handed. '); }
;
/*
* descContentsLister displays a list of miscellaneous contents of an object
* being examined.
*/
descContentsLister: ItemLister
/* is the object listed in an EXAMINE description of its container? */
listed(obj) { return obj.examineListed && !obj.isHidden; }
contentsListedProp = &contentsListedInExamine
;
/*
* openingContentsLister displays the contents of an openable container when
* it is first opened.
*/
openingContentsLister: ItemLister
/* is the object listed in an EXAMINE description of its container? */
listed(obj) { return obj.examineListed && !obj.isHidden; }
/*
* We don't want recursive listing with the openingContentsLister, since
* this can produce odd results.
*/
listRecursively = nil
;
/*
* lookInLister is used to list the contents of an object in response to LOOK
* IN/UNDER/BEHIND
*/
lookInLister: ItemLister
/*
* is the object listed in a SEARCH/LOOK IN/UNDER/BEHIND description of
* its container?
*/
listed(obj) { return obj.searchListed && !obj.isHidden; }
contentsListedProp = &contentsListedInSearch
;
/* A lister used to list the items attached to a SimpleAttachable */
simpleAttachmentLister: ItemLister
/* an object is listed if it's attached */
listed(obj) { return obj.attachedTo != nil && !obj.isHidden; }
;
/* A lister used to list the items plugged into a PlugAttachable */
plugAttachableLister: simpleAttachmentLister
;
/*
* A lister that can be readily customized to tailor the text before and after
* a list of miscellaneous items in a room description.
*/
class CustomRoomLister: ItemLister
/* is the object listed in a LOOK AROUND description? */
listed(obj) { return obj.lookListed && !obj.isHidden; }
/*
* In the simple form of the constructor, we just supply a string that
* will form the prefix string for the lister. In the more sophisticated
* form we can supply an additsion argument that's an anonymous method or
* function that's used to show the list prefix or suffix, or else just
* the suffix string.
*/
construct(prefix, prefixMethod:?, suffix:?, suffixMethod:?)
{
prefix_ = prefix;
if(prefixMethod != nil)
setMethod(&showListPrefix, prefixMethod);
if(suffix != nil)
suffix_ = suffix;
if(suffixMethod != nil)
setMethod(&showListSuffix, suffixMethod);
}
prefix_ = nil
suffix_ = '. '
showListPrefix(lst, pl, irName)
{
"<.p><<prefix_>> ";
}
showListSuffix(lst, pl, irName)
{
"<<suffix_>>";
}
showSubListing = (gameMain.useParentheticalListing)
;
Adv3Lite Library Reference Manual
Generated on 03/07/2024 from adv3Lite version 2.1