musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
#ifndef MUDOBJECT_H
#define MUDOBJECT_H

#include <set>
#include <string>
#include <bitset>

#include <time.h>

using namespace std;

#include "flags.h"
#include "pflags.h"
#include "newprint.h"
#include "Object.h"
#include "World.h"

class Mission;

class MudObject;
class PagerState;

//! a filter
class showto {
 public:
  virtual bool operator()(const MudObject *) const = 0;
  virtual ~showto();
};

//! an actual concrete in-game object with location, name, etc.
class MudObject : public Object {
 private:
  bitset<512> flags, resetflags;
  bitset<512> granted, withheld, abeyed;

  void q_update();
  void q_remove();

 public:
    //! does it have the pflag?
    bool get_priv(PFlag) const;

    //! has it been granted the flag?
    bool get_apriv(PFlag) const;

    //! has it been granted the flag?
    bool get_gpriv(PFlag) const;

    //! has it been withheld from the flag?
    bool get_wpriv(PFlag) const;

    //! would it have the priv?
    bool get_dpriv(PFlag) const;


    void set_wpriv(PFlag, int);
    void set_apriv(PFlag, int);
    void set_gpriv(PFlag, int);

    //! get flag
    bool get_flag(Flag) const;
    //! get reset-flag
    bool get_rflag(Flag) const;

    //! set flag
    void set_flag(Flag, bool);

    //! set reset flag
    void set_rflag(Flag, bool);

    //! set both flags
    void set_bflag(Flag a, int b) {
      set_flag(a, b);
      set_rflag(a, b);
    }

    //! a file output has been diverted to
    FILE *of;

    //! the zone associated with this object
    MudObject *zone;

    //! the mission this object is associated with
    Mission *mission;

    //! times for next actions
    time_t next_time, wander_time, rant_time;

    //! objects that are snooping this one
    World<MudObject> snoopers;

    //! objects this object is snooping
    World<MudObject> snooping;

    //! what this object is following
    MudObject *follows;

    //! things that are following this object
    World<MudObject> followers;

    //! objects this is tracing
    World<MudObject> tracing;

    //! objects that are tracing this
    World<MudObject> tracers;

    //! divert output to given file
    void file_divert(FILE *f);
    
    //! restore output to normal channel
    void file_undivert();
  
    //! snoop on /who/
    bool snoop(MudObject *who) {
      if (!who->snoopers.get(this->id)) {
	who->snoopers.add(this);
	snooping.add(who);
	return 1;
      }
      return 0;
    }

    //! stop snooping /who/
    void desnoop(MudObject *who) {
      if (who->snoopers.get(this->id)) {
	who->snoopers.remove(this);
	snooping.remove(who);
      }
    }

    //! follow /who/
    void follow(MudObject *who) {
      if (follows==who)
	return;
      if (follows) {
	follows->followers.remove(*this);
      }
      follows = who;
      if (follows) {
	follows->followers.add(*this);
      }
    }

    //! thing for routefinding
    struct {
      int s;
      MudObject *exit;
    } l;

    //! whether this object temporarily has max privs
    int ilc;

    //! quests this object has done
    std::set<string> quests;

    //! the last time this object was referenced
    time_t reftime;
    
    //! update the reftime to now
    void ref();

    //! construct the object with given id
    MudObject(const char *);
    ~MudObject();
    
    //! objects in this object
    World<MudObject> *children;

    //! object this object is in
    MudObject *owner;

    //! how many players are in this object
    int players_here;

    //! associate this object with mission
    void set_mission(Mission *m);

    //! holo_clone this object from given object
    virtual void holo_clone(const MudObject *, const char *);
    
    //! format and send
    virtual void printf(const char *what, PRINT_ARGS);
    
    //! format and send to every object in owner->children that the filter likes (apart from this)
    void oprintf(const showto &, const char *what, PRINT_ARGS);

    void oprintf(const char *what, PRINT_ARGS);

    //! print to everything here
    virtual void aprintf(const char *what, PRINT_ARGS);
      
    void real_aprintf(const showto &f, const char *a, const PARMS &p, MudObject *target);

    //! format and send to every object in linked rooms to owner that the filter likes (apart from this)
    void lprintf(const showto &, const char *what, PRINT_ARGS);

    //! format an action and send it to this (this = the source)
    virtual void action_to(MudObject *target, const char *format, const char *text=0, MudObject *prop=0);

    //! format an action and send it to this (this = the target)
    virtual void action_from(MudObject *source, const char *format, const char *text=0, MudObject *a=0,
			                                                                MudObject *prop=0);

    //! format an action and send it to others
    virtual void action(MudObject *target, const char *format, const char *text=0, MudObject *prop=0);

    //! format an action and send it to others
    virtual void action(const showto &, MudObject *target, const char *format, const char *text=0, MudObject *prop=0);

    //! return the depth of this object in the tree
    int depth() const { if (!owner) return 0; return owner->depth()+1; }
    
    //! reset this object
    virtual void reset();    

    //! unreset this object
    virtual void unreset() {
      resetflags = flags;
    }
    
    //! execute given command
    bool interpret(const char *);

    //! format and execute given command
    bool interpretf(const char *, PRINT_ARGS);

    //! execute given command with lots of privs
    bool interpret2(const char *a) {
      ilc++;
      bool q = interpret(a);
      ilc--;
      return q;
    }
    //! send file to object for paging
    virtual bool spewfile(const char *,const char *,bool=true,const char* ="");
    //! poll object
    virtual void execute();
    //! send cached data
    virtual void send_data();
    
    virtual void push_data();

    //! clone object from given object
    void clone(const MudObject *);

    //! save object to file
    void save(FILE *f, bool include_var=false) const;

    //! parse a line of a loaded file
    void load(const char *);

    //! save vardata to file
    void save_var(FILE *f) const;

    //! get string property off object
    virtual const char *get(const char *) const;

    //! set object property on object
    void set(const char *k, MudObject *o) {
      set(k, o?o->id:0);
    }
    //! set int property on object
    virtual void set(const char *, int);
    //! set string property on object
    virtual void set(const char *, const char *);

    //! format string and set it on object
    void setf(const char *, const char *, PRINT_ARGS);

  void set(const string &k, const string &v) {
    set(k.c_str(), v.c_str());
  }

  //! get object property
    virtual MudObject* get_object(const char *) const;

    //! save the difference between this and ofwhat to f
    void save_difference(FILE *f, const MudObject *ofwhat) const;

    //! return the size of array
    int array_size(const char *aname) const;

    //! return string at aname[index]
    const char *array_get(const char *aname, int index) const;

    //! return integer at aname[index], defaulting to def
    int array_get_int(const char *aname, int index, int def=-1) const;

    //! return object at aname[index]
    MudObject *array_get_object(const char *aname, int index) const;

    //! set aname[index] to what
    void array_set(const char *aname, int index, MudObject *what);

    //! set aname[index] to what
    void array_set(const char *aname, int index, int what);

    //! set aname[index] to what
    void array_set(const char *aname, int index, const char *what);

    //! set aname[index].prop to val
    void array_set(const char *aname, int index, const char *prop, int val);

    //! set array[index].prop to val
    void array_set(const char *aname, int index, const char *prop, const char *val);

    //! set array[index].prop to val
    void array_set(const char *aname, int index, const char *prop, MudObject *val);

    //! get array[index].prop as integer
    int array_get_int(const char *aname, int index, const char *prop, int def=-1) const;

    //! get array[index].prop as string
    const char *array_get(const char *aname, int index, const char *prop) const;

    //! get array[index].prop as object
    MudObject *array_get_object(const char *aname, int index, const char *prop) const;

    //! remove array[index]
    void array_unset(const char *aname, int index);

    //! remove array[index].prop
    void array_unset(const char *aname, int index, const char *prop);
    
    //! speculatively print
    void spec_printf(const char *fmt, PRINT_ARGS);
    
    //! speculatively print
    //    virtual void spec_vprintf(const char *fmt, va_list v);

    //! format and send
    virtual void real_printf(const char *what, const PARMS &p, MudObject *target=NULL, int snoop=0);

    virtual void real_spec_printf(const char *what, const PARMS &p);

    //    virtual void voprintf(const showto &, const char *, va_list v);

    //! abort speculative print
    virtual bool cancel_printf();

    //! trace on /who/
    bool trace(MudObject *who) {
      if (!who->tracers.get(this->id)) {
	who->tracers.add(this);
	tracing.add(who);
	return 1;
      }
      return 0;
    }

    //! stop tracing /who/
    void detrace(MudObject *who) {
      if (who->tracers.get(this->id)) {
	who->tracers.remove(this);
	tracing.remove(who);
      }
    }
};

//! a filter
typedef bool(*fn_t)(MudObject*);

class Verb;

//! obtain a verb with id /verbname/
Verb *get_verb(const char *verbname);

#endif