untermud/DOC/
untermud/DOC/U/
untermud/DOC/U/U-examples/
untermud/DOC/internals/
untermud/DOC/wizard/
untermud/MISC/
untermud/MISC/dbchk/
untermud/RWHO/
untermud/RWHO/rwhod/
#include "copyright.h"

#ifndef __DB_H
#define __DB_H
#include <stdio.h>

extern void *malloc (unsigned long);
extern void *realloc (void *, unsigned long);
extern void free (void *);

#ifdef TEST_MALLOC
extern int malloc_count;
#define malloc(x) (malloc_count++, malloc(x))
#define free(x) (malloc_count--, free(x))
#endif /* TEST_MALLOC */

typedef int dbref;              /* offset into db */

#define TYPE_ROOM 	0x0
#define TYPE_THING 	0x1
#define TYPE_EXIT 	0x2
#define TYPE_PLAYER 	0x3
#ifdef RECYCLE
#define TYPE_GARBAGE	0x6
#endif
#define NOTYPE		0x7     /* no particular type */
#define TYPE_MASK 	0x7     /* room for expansion */
#define ANTILOCK	0x8     /* negates key (*OBSOLETE*) */
#define WIZARD		0x10    /* gets automatic control */
#define LINK_OK		0x20    /* anybody can link exits to this room */
#define DARK		0x40    /* contents of room are not printed */
#define TEMPLE		0x80    /* objects dropped in this room go home */
#define STICKY		0x100   /* this object goes home when dropped */

#ifdef RESTRICTED_BUILDING
#define BUILDER		0x200   /* this player can use construction commands */
#endif /* RESTRICTED_BUILDING */

#define HAVEN           0x400   /* this room prohibits killing */
#define ABODE           0x800   /* can link objects or players here */

#ifdef GENDER
#define GENDER_MASK	0x3000  /* 2 bits of gender */
#define GENDER_SHIFT	12      /* 0x1000 is 12 bits over (for shifting) */
#define GENDER_UNASSIGNED	0x0     /* unassigned - the default */
#define GENDER_NEUTER	0x1     /* neuter */
#define GENDER_FEMALE	0x2     /* for women */
#define GENDER_MALE	0x3     /* for men */

#ifdef ROBOT_MODE
#define ROBOT		0x4000  /* Can set OUTPUTPREFIX */
#endif  /* ROBOT_MODE */

#define UNWANTED        0x8000  /* can be chowned */

#define TABULAR_WHO     0x10000
#define REVERSED_WHO    0x20000

#define Genderof(x) ((db[(x)].flags & GENDER_MASK) >> GENDER_SHIFT)
#endif /* GENDER */

typedef int object_flag_type;

#define Flag(x,f) ((db[(x)].flags & (f)) != 0)

#define Typeof(x) (db[(x)].flags & TYPE_MASK)
#define Wizard(x) ((db[(x)].flags & WIZARD) != 0)
#ifdef ROBOT_MODE
#define Robot(x) ((db[(x)].flags & ROBOT) != 0)
#endif  /* ROBOT_MODE */
#define Dark(x) ((db[(x)].flags & DARK) != 0)
#ifdef GOD_PRIV
#define GOD ((dbref)1)
#define	God(x) ((x)==GOD)
#endif  /* GOD_PRIV */

#ifdef RESTRICTED_BUILDING
#define Builder(x) ((db[(x)].flags & (WIZARD|BUILDER)) != 0)
#endif /* RESTRICTED_BUILDING */

/* Boolean expressions, for locks */
typedef char boolexp_type;

#define BOOLEXP_AND 0
#define BOOLEXP_OR 1
#define BOOLEXP_NOT 2
#define BOOLEXP_CONST 3

struct boolexp {
  boolexp_type type;
  struct boolexp *sub1;
  struct boolexp *sub2;
  dbref thing;
};

#define TRUE_BOOLEXP ((struct boolexp *) 0)

/* special dbref's */
#define NOTHING (-1)            /* null dbref */
#define AMBIGUOUS (-2)          /* multiple possibilities, for matchers */
#define HOME (-3)               /* virtual room, represents mover's home */

struct object {
  const char *name;
  const char *description;
  dbref location;               /* pointer to container */
  /* for exits, pointer to destination */
  dbref contents;               /* pointer to first item */
  dbref exits;                  /* pointer to first exit for rooms */
  /* pointer to home for things and players */
  dbref next;                   /* pointer to next in contents/exits chain */
  dbref source;                 /* Where exits are. */

  /* the following are used for pickups for things, entry for exits */
  struct boolexp *key;          /* if not NOTHING, must have this to do op */
  const char *fail_message;     /* what you see if op fails */
  const char *succ_message;     /* what you see if op succeeds */
  /* other messages get your name prepended, so if your name is "Foo", */
  /* and osuccess = "disappears in a blast of gamma radiation." */
  /* then others see "Foo disappears in a blast of gamma radiation." */
  /* (At some point I may put in Maven-style %-substitutions.) */
  const char *ofail;            /* what others see if op fails */
  const char *osuccess;         /* what others see if op succeeds */

  dbref owner;                  /* who controls this object */
  int pennies;                  /* number of pennies object contains */
  object_flag_type flags;
  const char *password;         /* password for players */
#ifdef TIMESTAMPS
  /* Timestamp mod, Sep 1, 1990 by Fuzzy */
  long created;                 /* Time of creation */
  long lastused;                /* Time last used/entered */
  long usecnt;                  /* Times used/entered */
#endif
};

extern struct object *db;
extern dbref db_top;

extern const char *alloc_string (const char *s);

extern dbref new_object ();     /* return a new object */

extern dbref getref (FILE *);   /* Read a database reference from a file. */

extern void putref (FILE *, dbref);     /* Write one ref to the file */

extern struct boolexp *getboolexp (FILE *);     /* get a boolexp */
extern void putboolexp (FILE *, struct boolexp *);      /* put a boolexp */

extern int db_write_object (FILE *, dbref);     /* write one object to file */

extern dbref db_write (FILE * f);       /* write db to file, return # of objects */

extern dbref db_read (FILE * f);        /* read db from file, return # of objects */
                                /* Warning: destroys existing db contents! */

extern void free_boolexp (struct boolexp *);
extern void db_free (void);

extern dbref parse_dbref (const char *);        /* parse a dbref */

#define DOLIST(var, first) \
  for((var) = (first); (var) != NOTHING; (var) = db[(var)].next)
#define PUSH(thing, locative) \
    ((db[(thing)].next = (locative)), (locative) = (thing))
#define getloc(thing) (db[thing].location)

/*
  Usage guidelines:

  To refer to objects use db[object_ref].  Pointers to objects may 
  become invalid after a call to new_object().

  The programmer is responsible for managing storage for string
  components of entries; db_read will produce malloc'd strings.  The
  alloc_string routine is provided for generating malloc'd strings
  duplicates of other strings.  Note that db_free and db_read will
  attempt to free any non-NULL string that exists in db when they are
  invoked.  
*/
#endif /* __DB_H */