Hopefully someone can find this useful. Written in adv3 but could easily be adapted to Lite…
enum leftSide, rightSide ;
/* NOTE: if you are using border banners, or any other banners that subdivide the window sooner than the inventory window, you will have to make the appropriate changes here, to determine which banner this should be shown after */
inventoryWindow: BannerWindow
alignTo = leftSide
/* it would be nice to be able to use sizeToContents(), but then items with a space in their names are likely to be broken into two rows */
size = 23 /* user's preference: I tended towards narrow, and used terse inventory names */
show() {
showBanner(nil, BannerAfter, statuslineBanner, BannerTypeText,
alignTo==leftSide ? BannerAlignLeft : BannerAlignRight, size, BannerSizeAbsolute, BannerStyleVScroll);
invNote();
}
initBannerWindow() {
if(inited_) return;
statuslineBanner.initBannerWindow();
inherited();
}
;
inventoryWindowDaemon: PromptDaemon, InitObject
execute() { construct(self, &beforePrompt); }
beforePrompt() {
//if(any special conds such as being in an intro screen) return;
if(invChanged) {
local save = InventoryAction.inventoryMode;
try {
gPlayerChar.usingInvWin = true;
InventoryAction.inventoryMode = InventoryTall;
/*I forced a typewriter font in the invwin so that indenting to show containment will look consistent and balanced. */
local str = '<tt>' + mainOutputStream.captureOutput({:gPlayerChar.showInventory(true)}) + '</tt>';
inventoryWindow.clearWindow();
inventoryWindow.writeToBanner(str);
}
finally {
InventoryAction.inventoryMode = save;
invChanged = nil;
gPlayerChar.usingInvWin = nil; } } }
invChanged = nil
;
function invNote() { inventoryWindowDaemon.invChanged = true; }
modify me /* or whatever your PC is named */
usingInvWin = nil
inventoryLister { if(usingInvWin) return invWinLister; else return stdInvLister; }
stdInvLister: actorSingleInventoryLister { /* */}
invWinLister: actorSingleInventoryLister {
contentsListedSeparately(obj) { return nil; }
showListIndent(options, indent)
{ if ((options & ListTall) != 0)
{ for (local i = 0 ; i + 1 < indent ; ++i) "\ \ "; } }
showListContentsPrefixTall(itemCount, pov, parent)
{ "<<parent.listName>>"; }
showContentsList(pov, obj, options, indent, infoTab)
{ obj.showInventoryContents(pov, gPlayerChar.invWinLister, options, indent, infoTab); }
//* using invWinLister instead of ctsLister ^ ^
showInlineContentsList(pov, obj, options, indent, infoTab)
{ obj.showInventoryContents(pov, gPlayerChar.invWinLister, options, indent, infoTab); }
/* an example of sticking something at the top of the list: perhaps a bag of holding */
showArrangedList(a,parent,lst,c,indent,e,f,g,h,i,j) {
local ix = lst.indexOf(burlap);
if(ix) {
lst = lst.removeElementAt(ix);
lst = lst.insertAt(1,burlap);
}
inherited(a,parent,lst,c,indent,e,f,g,h,i,j);
}
/* ComplexContainers in inventory look wonky without special treatment. A simplistic approach is to tell the ComplexComponent subLocations not to list their contents, because we will modify the ComplexContainer to gather all of its subLocations' contents in one list */
contentsListed(obj) { return obj.ctsListed && !obj.oK(ComplexComponent); }
;
modify Thing
listName = (gPlayerChar.usingInvWin ? invWinName : inherited)
invWinName = name
/* here we alert the inventory window to refresh its contents */
baseMoveInto(newContainer) {
if(location && location.isOrIsIn(gPlayerChar) || newContainer && newContainer.isOrIsIn(gPlayerChar))
invNote();
inherited(newContainer); }
;
modify ComplexContainer
getListedContents(lister, infoTab) {
if(lister==gPlayerChar.invWinLister) {
local vec = new Vector(10);
foreach(local cont in allSubLocations) {
if(cont) {
foreach(local cur in cont.contents) vec.append(cur);
}
}
return vec.subset({x: lister.isListed(x)});
}
else return getContentsForExamine(lister, infoTab).subset({x: lister.isListed(x)});
}
;