!
! OKBLib        -       OKB's personal library of stuff
! Not intended for public release

System_file;

Attribute OwnParagraph;

       Class Room
has light
with name 'room' 'wall' 'walls';

       Class AutoRoom
class Room
with describe [;
if (self.description) PrintOrRun(self,description);
TreeWalk(self,AutoRoomDescribe);
print "^"; rtrue;
];

[AutoRoomDescribe obj depth iteration x;
               if (obj provides describe) {
       if (obj has OwnParagraph) print "^";
       if (obj hasnt OwnParagraph && iteration>1) print "  ";
       switch (metaclass(obj.describe)) {
String: print (string) obj.describe; x=1;
Routine: x=obj.describe(depth,iteration);
Object: x=AutoRoomDescribe(obj.describe);
default: x=0;
       }
       give obj concealed;
       if (x) rtrue;
       else rfalse;
               }
rfalse;
];

       Class Thing             ! This lets the contents of containers be printed automatically
with after [a b;
Examine: if (self hasnt supporter && (self hasnt container || TestScope(child(self)==0))) rfalse;
if (self has pluralname) b=" them."; else b=" it.";
if (children(self)<1) {print "There's nothing ";
if (self has supporter) print "on"; else print "in"; " it.";}
if (self has supporter) print "On "; else print "In "; print (the) self;
objectloop (a in self) {if (a has concealed) give a ~workflag; else give a workflag;}
WriteListFrom(child(self),ENGLISH_BIT+RECURSE_BIT+ISARE_BIT+WORKFLAG_BIT);
"."; ];

       Class Decor             ! Purely scenery
has scenery
with description [; if (noun hasnt pluralname) print "It's just a regular ",(name) self,".  ";
else print "They're just regular ",(name) self,".  "; ],
after [a;
Examine:
       if (self hasnt supporter && (self hasnt container || TestScope(child(self))==0)) {
if (self.description~=self.Decor::description) rtrue; else "Nothing special.";
       }
       if (children(self)<1) {
print "There's nothing ";
if (self has supporter) print "on"; else print "in";
" it.";
       }
if (self has supporter) print "On "; else print "In "; print (the) self;
       objectloop (a in self) {
if (a has concealed) give a ~workflag; else give a workflag;
       }
WriteListFrom(child(self),ENGLISH_BIT+RECURSE_BIT+ISARE_BIT+WORKFLAG_BIT);
".";
];

[PausePrompt message;
print (string) message;
KeyCharPrimitive();
];

! TreeWalk(root, func) -- Walks the object tree, starting at (but not including) root.  func may be an actual routine, or a property name.  If it is a routine, func(obj,depth,iteration) is called for each obj in the tree.  If it is a property, obj.func(obj,depth,iteration) is called for each obj in the tree.
!       In all cases, depth is the depth of recursion -- for direct children of root it is 1, for grandchildren it is 2, etc.  At any given depth, iteration is the relative "age" of obj compared to its siblings -- for the eldest child it is 1, for the second 2, etc.
[TreeWalk root func depth iteration i tempfunc;
depth=1;
       for (i=child(root) : i : i=sibling(i)) {
iteration++;
if (metaclass(func)==nothing) tempfunc=i.func;
else tempfunc=func;
indirect(func, i, depth, iteration);
TreeWalk(i,func,depth);
       }
depth--;
return; ];

! RandRange(min,max) -- returns a random number x such that min <= x <= max
[RandRange min max;
return random(max-min+1)+min-1;
];

! ObjName -- printing rule to get an object's internal source-code name
! Why doesn't the library already provide this?
[ObjName a;
if (a) print (object) a;
else print "nothing";
];

[Die n;
deadflag=n;
print "^^    ";
       #ifdef TARGET_ZCODE;
#IFV5; style bold; #ENDIF;
       #ifnot; ! TARGET_GLULX
glk($0086, 5); ! set alert style
       #endif; ! TARGET_

print "***";
if (n==1) L__M(##Miscellany,3);
if (n==2) L__M(##Miscellany,4);
if (n>2)  { print " "; DeathMessage(n); print " "; }
print "***";

       #ifdef TARGET_ZCODE;
#IFV5; style roman; #ENDIF;
       #ifnot; ! TARGET_GLULX
glk($0086, 0); ! set normal style
       #endif; ! TARGET_
print "^^^";
ScoreSub();
DisplayStatus();
AfterGameOver();
];