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 MISC_H
#define MISC_H

#include <sys/stat.h>
#include <sys/types.h>

#include "musicmud.h"
#include "flags.h"
#include "util.h"
#include "missions.h"
#include "pos.h"
#include "move.h"
#include "rooms.h"
#include "vsprintf.h"
#include "format.h"
#include "eq.h"
#include "zoneload.h"

#define SIZE_INFINITE (1 << 30)

#define LOG_INFO 1000000

// BASIC UTILITY FUNCTIONS

#define is_mission(o) (o->get(KEY_ACCEPTER) || o->get_flag(FL_MISSION) || o->get_flag(FL_QUEST))

//! is the given string an affirmitive? (yes, true, 1)
int yes(const char *);
//! is the given string a negative (no, false, 0)
int no(const char *);
//! convert the string to all lower case. not colour-safe.
string make_lower(const char *s);
//! search for /needle/ in /haystack/ safely. return true if found.
bool sstrstr(const char *haystack, const char*needle);
//! return true if one of the strings in argv[argc] is /what/
bool strhas(int argc, const char **argv, const char *what);
//! capitalise the first letter of what
string capitalise(string what);

//! return the name of /what/, stripped of colour
string bw_name(MudObject *what);
#define bwname(a) ((bw_name(a).c_str()))

//! there is a 1 in odds chance this will return true
bool random_chance(long odds);
//! return a random number >= 0 and < limit.
long random_number(long limit);

//! wildcard match pattern against string
bool wcmatch (const char *pattern, const char *string);

//! return true if c is a vowel in english (aeiou)
bool isvowel(char c);

//! return the id of the original version of o if its a clone, or its id
const char *drillid(MudObject *o);

// ENGLISH

//! convert a small cardinal number to a string
const char *numbertostring(int number);
//! remove any articles from frase
const char *remove_articles(const char *frase) ;
//! try to pluralise the given prase
string plural_phrase(const char *frase);
//! return the plural name of /obj/. islong is set to indicate if 'long' should be used
string plural_name(MudObject *obj, int islong=0);

// I18N stuff

//! translate the string msg, spoken by the speaker what
const char *lang(const char *msg, MudObject *what);


// BASIC IO FUNCTIONS

//! return true if either of the args contain a . or a /
bool hack_attempt(const char *, const char *);

// PLAYER FILE FUNCTIONS
//! return true if a player file exists with given name
bool player_exist(const char *name);
//! look up the coloured and capitalised name of offline player
string lookup_name(const char *who);
string lookup_name(string who);

// MESSAGING FUCNTIONS

//! format and broadcast text to everyone
void broadcast(const char *txt, PRINT_ARGS);
//! format and broadcast text to everyone the filter doesn't reject
void broadcast(const showto &, const char *txt, PRINT_ARGS);

//! foramt and send a message to everyone on the ship
void shipmsg(MudObject *ship, const char *fmt, PRINT_ARGS);

// LOTTERY

//! pick a random object from given loc ic
MudObject* choose_random_object_from(const char *where);
//! pick a random object from given loc (if function given, from those that the function returns true on)
MudObject* choose_random_object_from(MudObject *where, fn_t whether=0);
//! pick a random player from given loc
MudObject* choose_random_player_from(MudObject *where);

// INTERNAL MUD INFO QUERYING

//! which player is ranked higher in who?
int player_rank(const void *first, const void *second);

//! return if child is in parent at all.
bool is_in(MudObject *child, MudObject *parent);

//! return the state of what
int state(const MudObject *what);

//! return current (holo)strength of who
int strength_of(const MudObject *who);

//! set current strength of who to s
void set_strength(MudObject *who, int s);

//! is what visible to to
bool visible_to(const MudObject *to, const MudObject *what);

//! return the invis level of given object
int invis(const MudObject *);

//! the hour and minute of a time in a particular place in the mud.
struct mudtime_t {
  int hour;
  int min;
};

//! return the mud time at a location
mudtime_t mudtime(MudObject *where);

#define is_mobile(w) (w->get_flag(FL_MOBILE))
//! return true if who is a mobile or a player
inline bool is_person(MudObject *who) { return is_player(who) || is_mobile(who); }
//! return true if who is a mobile that cannot be picked up
bool is_big_mobile(MudObject *what);

//! find out what location /who/ would save in, and return it
MudObject *saveloc(MudObject *who);

//! return the type of body that /who/ has
const char *body(const MudObject *who);

//! return the species of /who/
const char *species(const MudObject *who);

//! return the floor in /where/
MudObject *floor(MudObject *where);

//! return true if /where/ is lit.
bool has_light(MudObject *where, bool def=true);

//! return the serving of what
int serving(MudObject *what);

//! return the alcohol by %age of what
int abv(MudObject *what);

//! return the value of /what/
int object_value(MudObject *what);

//! return true if /what/ will fit into /into/
bool will_fit(MudObject *what, MudObject *into);

//! is /what/ low enough for /who/ to put stuff on and take stuff from?
bool low_enough(MudObject *who, MudObject *what);

//! is /what/ low enough for /who/ to put stuff on and take stuff from?
bool shelf_low_enough(MudObject *who, MudObject *what);

//! return true if the world /w/ should be treated as plural
bool plural(const NewWorld &w);

//! if /exit/ is a link to a LINKED room which can be seen into, return the room, otherwise null.
MudObject *linkedlink(MudObject *exit);

//! return any pit in loc
MudObject *find_pit(MudObject*);

// DOCKING/SHIP STUFF
//! empty the given ship
void empty_ship(MudObject *where);
//! does player who have permission to dock at where
bool has_rights(MudObject *who, MudObject *where);
//! find a free dock at docklist. if ignore specified, don't return that.
MudObject *find_dock(MudObject *docklist, MudObject *ignore=0);
//! find the ship in given dock
MudObject *find_ship(MudObject *dock); 

// INTERNAL MUD PRIMITIVE MANIPULATION

//! move what to dest
void set_owner(MudObject * what, const char *dest);
//! move what to dest
void set_owner(MudObject *what, MudObject *dest);
//! move contents of what to where
void dumpstuff(MudObject *what, MudObject *where);

//! Dispose of an object.  If it's a clone it will be marked for deletion as 
//! soon as safe.  If it's a real object then it will be moved to 'empty'.
void vanish(MudObject *what);
//! kill what and its contents, recursively
void vanish_contents(MudObject *what);
//! vanish o and replace it with a clone of the object it its 'empty' property, if there is one.
MudObject *replace_with_empty(MudObject *o);

// INTERNAL MUD COMMANDS

NewWorld try_remove_obs(MudObject *who, NewWorld stuff);

//! make /player/ give /what/ to /dest/
bool internal_give(MudObject *player, MudObject *what, MudObject *dest, bool traps=true);
//! cause /who/ to drop /what/. triggers all traps. dothrow to indicate a throw, docareful to idnicate put on floor, thrownat to indicate the target of a throw if any.
void drop_obs(MudObject *who, NewWorld what, bool dothrow=false, bool docareful=false, TeleObject thrownat=TeleObject());
//! turn /ofwhat/ into a corpse in /where/
MudObject *make_corpse(MudObject *ofwhat, MudObject *where);
//! interpret a semicolon-delimited str with who
void itell(MudObject *who, const char *str);

//! clones an object
/*!
   \param who the object to clone
   \param dest to place the clone
   \param new_id the id for the new object (default is usually ok)
   \param flags 1 to indicate that auto objects should be created on the clone
   \param zone a string to set the zone property on the clone to (default is "@auto")
 */
MudObject *clone_object(MudObject *who, MudObject *dest=0, const char *new_id=0, int flags=0, const char *zone=0);

//! make /who/ heal /what/ by /healing/
bool heal(MudObject *who, MudObject *what, int healing);

//! return true if object can be dropped
bool is_droppable(MudObject *);

// INTERNAL MUD SECURITY FUNCTIONS

//! is /who/ in the comma-seperated list /inwhat/?
bool permitted_access(MudObject *who, const char *inwhat);
//! is /id/ in the comma-seperated list /inwhat/?
bool permitted_access(const char *id, const char *inwhat);
//! exclude /id/ from comma-seperated list /inwwhat/, return new list
const char *uninvite(const char *id, const char *inwhat);
bool can_affect(const MudObject *, const char *);
bool cantouch_zone(const MudObject *who, const char *zonestr);
bool is_author(MudObject *who, MudObject *what);

// ZONE STUFF
//! return the _zone object associated with /where/
MudObject *zoneof(MudObject *where);
//! return the _zone object for /zonestr/
MudObject *getzone(const char *zonestr);
//! get area property /prop/, starting at /wh/ and chaining 
const char *get_zoneprop(MudObject *wh, const char *prop, const char *def=0);
//! get area property /prop/, starting at /wh/ and chaining 
int get_zonepropint(MudObject *wh, const char *prop, int def=-1);
//! get area property /prop/, starting at /wh/ and chaining 
inline MudObject *get_zonepropobj(MudObject *wh, const char *prop) {
  const char *c=get_zoneprop(wh, prop);
  if (c) return planet->get(c);
  return 0;
}
//! find the coproom applying for this room
MudObject *find_coproom(MudObject *who);

// RANDOM STUFF

//! return an error message for attempting to put an object in itself
const char*get_wierd();

//! return who's quarters.
MudObject *quarters(MudObject *who);
//! find some free quarters
MudObject *find_free_quarters(MudObject *who);

//! is the object a container?
inline bool is_container(MudObject *o) { return o->get_flag(FL_CONTAINER); }

//! is the object openable?
inline bool is_canopen(MudObject *o) { return o->get_flag(FL_CANOPEN); }

//! is the object open?
inline bool is_open(MudObject*o) { return state(o)==0; }

//! set the open state of the object to i
inline void set_open(MudObject* o, bool i) { o->set(KEY_STATE, i ? 0 : 1); }

//! is the object on fire or lit?
inline bool is_lit(MudObject *o) { return o->get_flag(FL_LIT) || o->get_flag(FL_ONFIRE); }

bool is_dark(MudObject *o);

//! is the object locked?
inline bool is_locked(MudObject *o) { return state(o)==2; }

//! set this object to locked or not
inline void set_locked(MudObject *o, bool i) { o->set(KEY_STATE, i?2:1); }

//! can this be locked?
inline bool is_canlock(MudObject *o) { return o->get_flag(FL_CANLOCK); }

//! is this an exit?
inline bool is_exit(MudObject* o) { return o->get_flag(FL_EXIT); }

//! is this closed?
inline bool is_closed(MudObject *o) { return state(o)>0; }

//! return a random number between 0 and 99.
inline int randperc() { return random_number(100); }

//! return a unique clone name
string get_clone_name();

//! name a mobile with a random name. will set gender, name, surname, forename, short
void name_mobile(MudObject*);

//! return a random placename
string random_placename();
//! return a random ship name
string random_shipname();
//! return a random warship name
string random_warshipname();
//! return a random surname
string random_surname();
//! return a random male forename
string random_male();
//! return a random female forename
string random_female();

#define DAY (24 * 60 * 60)
#define HOUR (60 * 60)
#define MINUTE (60)

#include "shared.h"

//! return a random tip of the day
string random_tip();

//! add the storeable equipment held by player into the world.
void add_storeable_eq(MudObject *, NewWorld &);

void recurse_clone(MudObject *, MudObject *, MudObject *, MudObject *, Mission *);
void remove_fakeids(MudObject *from);
void fixup_exits(MudObject *);
string genid(MudObject *);

class OfflinePlayer {
  bool del;
  MudObject *who;
public:
  bool temp() const {
    return del;
  }
  MudObject *on() {
    if (!del)
      return who;
    return 0;
  }
  void grab(MudObject *forwho, const char *id) {
    del = 0;
    who = get_player(forwho, id);
    if (who)
      return;

    FILE *f = xopen(DATA_USERS, id, "r");
    if (!f)
      return;

    who = new Player(id, 0);
    string buf = getline(f);
    while (buf != "}" && !feof(f)) {
      buf = getproperty(f);
      who->load(buf.c_str());
    }      
    xclose(f);
    del = 1;
  }
  OfflinePlayer(MudObject *who) : del(0), who(who) {
  }
  ~OfflinePlayer() {
    if (del)
      delete who;
  }
  operator const MudObject*() const {
    return who;
  }
  const Player*pl() {
    return dynamic_cast<Player*>(who);
  }
  bool operator !() {
    return !who;
  }
  bool person() {
    return is_mobile(who) || is_player(who);
  }
  const MudObject *operator->() {
    return who;
  }
};

#endif