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/
#include <signal.h>
#include <sys/time.h>
#include <setjmp.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <vector>

#include "musicmud.h"
#include "pflags.h"
#include "pflagnames.h"
#include "flags.h"
#include "flagnames.h"
#include "events.h"
#include "hooks.h"
#include "verbs.h"
#include "misc.h"
#include "State.h"
#include "eq.h"
#include "death.h"
#include "trap.h"
#include "units.h"
#include "Mission.h"
#include "msi.h"
#include "levels.h"

#include "nations.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
}

#include "luaif.h"

extern const char *sec_prop;
extern MudObject *sec_pl;
extern MudObject *sec_o1;
extern MudObject *sec_o2;
extern MudObject *sec_o3;
extern const char *sec_txt;
extern MudObject *sec_on;

void lundivert(MudObject *who, const char *s);
void ldivert(MudObject *who, const char *s);

void removetimer(const char *code);
string addtimer(MudObject *what, const char *code, int when);

NewWorld get_currencies() {
  MudObject *n = planet->get("nations_zone");
  if (!n)
    return NewWorld();
  MudObject *o;
  int i;
  NewWorld w;
  foreach(n->children, o, i) {
    if (hascurr(o))
      w.add(o);
  }
  return w;
}

NewWorld get_quests() {
  extern set<MudObject*> s_quests;
  NewWorld ret;
  typeof(s_quests.begin()) i = s_quests.begin();
  while (i != s_quests.end()) {
    ret.add(*i);
    i++;
  }
  return ret;
}

void give(MudObject *player, MudObject *what, MudObject *dest) {
  if (player == dest)
    return;

  if (is_in(dest, what)) 
    return;

  if (!is_person(dest))
    return;
    
  if (dest->get_flag(FL_SLEEPING)) {
    player->printf("%#M is asleep.\n", dest);
    return;
  }
  
  if (dotrap(E_ONGIVE, player, dest, what)) return;
  
  player->printf("You give %Y to %M.\n", what, dest);
  player->oprintf(avoid(dest) && cansee, "%#M %[gives/give] %P to %M.\n", player, what, dest);
  what->printf("%#M %[gives/give] you to %M.\n", player, dest);
  dest->printf("%#M %[gives/give] %P to you.\n", player, what);
  set_owner(what, dest);
  
  if (dotrap(E_AFTERGIVE, player, dest, what)) return;
  if (dotrap(E_AFTERGIVEN, player, what, dest)) return;
  
  return;
}


MudObject *clone_ship(MudObject *tpl, Mission *mis) {
  MudObject *sh = clone_object(tpl, planet->get("space"));
  if (!sh)
    return 0;

  sh->set_mission(mis);

  recurse_clone(0, tpl, sh, sh, mis);
  sh->setf("name", "^M[Insert Name Here]^n");

  fixup_exits(sh);
  remove_fakeids(tpl);

  sh->set_flag(FL_SHIP, 1);
  sh->set(KEY_STATE, 1);

  return sh;
}

struct Table {
  int argc;
  const char **argv;
  Table() : argc(0), argv(0) {
  }
  Table(int ac) : argc(ac), argv(0) {
    alloc();
  }
  Table(const Table &t) : argc(t.argc), argv(0) {
    alloc();
    for (int i=0;i<argc;i++)
      argv[i] = t.argv[i];
  }
  void operator=(const Table &t) {
    if (argv) { free(argv); argv = 0; }
    argc = t.argc;
    alloc();
    for (int i=0;i<argc;i++)
      argv[i] = t.argv[i];
  }
  void alloc() {
    if (!argv)
      argv = new const char *[argc];
    for (int i=0;i<argc;i++) {
      argv[i] = 0;
    }
  }
  ~Table() {
    delete [] argv;
  }
};

Table l_totable(lua_State *L, int idx) {
  int argc = lua_getn(L, idx);
  Table t(argc);

  for (int i=0;i<argc;i++) {
    lua_pushnumber(L, i+1);
    lua_gettable(L, idx);
    const char *l=lua_tostring(L, -1);
    t.argv[i] = l;
    lua_pop(L, 1);
  }

  return t;
}

bool l_isstringtable(lua_State *l, int idx)
{
  if (!lua_istable(l, idx))
    return 0;

  int argc = lua_getn(l, idx);
  for (int i=0;i<argc;i++) {
    lua_pushnumber(l, i+1);
    lua_gettable(l, idx);
    const char *str=lua_tostring(l, -1);
    lua_pop(l, 1);
    if (!str)
      return 0;
  }
  
  return 1;
}

World<MudObject> l_toworld(lua_State *L, int idx)
{
  World<MudObject> w;
  
  int argc = lua_getn(L, idx);
  for (int i=0;i<argc;i++) {
    lua_pushnumber(L, i+1);
    lua_gettable(L, idx);
    MudObject *o = l_getobject(L, -1);
    if (o)
      w.add(o);
    lua_pop(L, 1);
  }

  return w;
}

bool l_isworld(lua_State *L, int idx)
{
  if (!lua_istable(L, idx))
    return 0;
  
  int argc = lua_getn(L, idx);
  for (int i=0;i<argc;i++) {
    lua_pushnumber(L, i+1);
    lua_gettable(L, idx);
   MudObject *o = l_getobject(L, -1);
   lua_pop(L, 1);
   if (!o)
     return 0;
  }

  return 1;
}

int
tourn() {
  return mud->get_int("tournament", 0);
}

bool peaceful(MudObject *where)
{
  if (where->get_flag(FL_UNPEACEFUL)) return 0;
  if (where==mud) return 0;
  if (where->get_flag(FL_PEACEFUL)) return 1;
  return peaceful(where->owner);
}

int can_attack(MudObject *who, MudObject *what) {
  int unjust = 0;
  MudObject *coproom = 0;
  if (!tourn() || !who->get("tourn") || (is_player(what) && !what->get("tourn"))) {
    
    if (is_player(what) || is_mobile(what)) {
      if (peaceful(who->owner)) {
	  
	  coproom = find_coproom(who->owner);
	  
	  unjust = 1;
	  if (who->get_flag(FL_POLICE))
	    unjust = 0;
	  
	  if (streq(what->get("nation"), "evil"))
	    unjust = 0;
      }
    }      
  }

  if (!is_player(what) && dotrap(E_ONUNJUST, who, what, 0, 0)) {
    unjust = 0;
  }

  return !unjust;
}

MudObject *random_room_from_zone(const char *zone)
{
  int i;
  MudObject *o;
  NewWorld r;
  if (zones->get(zone))
    foreach(zones->get(zone)->children, o, i) {
    if (o->get_flag(FL_ROOM) && !o->get_flag(FL_NOQUIT) && 
	!o->get_flag(FL_PRIVATE)) {
      r.add(*o);
    }
  }
  if (r.getsize()==0)
    return 0;
  return r.get(random_number(r.getsize()));
}

void vanish_all(MudObject *o)
{
  World<MudObject> w = *o->children;
  int i;
  MudObject *p;
  foreach((&w), p, i) {
    vanish_all(p);
  }
  vanish(o);
}

MudObject *holdszone(MudObject *who, const char *z) 
{
  MudObject *o;
  int i;
  foreach(who->children, o, i) {
    if (streq(o->get("zone"), z))
      return o;
  }
  foreach(who->children, o, i) {
    MudObject *t = holdszone(o, z);
    if (t)
      return t;
  }
  return 0;
}

void allholdsflag(MudObject *o, Flag f, World<MudObject> &ret)
{
  if (o->get_flag(f))
    ret.add(o);
  if (!o->children)
    return;
  MudObject *c;
  int i;
  foreach(o->children, c, i)
    allholdsflag(c, f, ret);
}

World<MudObject> alltreatas(MudObject *o, MudObject *f)
{
  World<MudObject> ret;
  if (o==f || o->get_object("treatas")==f)
    ret.add(o);

  MudObject *p;
  int i;
  foreach(o->children, p, i)
    ret += alltreatas(p, f);

  return ret;
}

void allholdsclone(MudObject *o, MudObject *f, World<MudObject> &ret)
{
  if (o==f)
    ret.add(o);
  else if (o->get_object("cloneof")==f)
    ret.add(o);
  if (!o->children)
    return;
  MudObject *c;
  int i;
  foreach(o->children, c, i)
    allholdsclone(c, f, ret);
}

void dofine(MudObject *from, MudObject *to, int amount, MudObject *cur)
{
  if (!cur)
    cur = currency(from);

  if (amount<=0)
    return;

  set_balance(to, cur, balance(to, cur)-amount);
  from->interpretf(lang("say %M, you have been fined %s.", from), to, formatcash(amount, cur, 1));
  return;
}

void pay(MudObject *from, MudObject *to, int amount, MudObject *cur) 
{
  if (!cur)
    cur = currency(from);

  if (amount<=0)
    return;

  set_cash(to, cur, cash(to, cur)+amount);
  to->printf("%#M %[pays/pay] you %s.\n", from, formatcash(amount, cur, 1));
  to->oprintf("%#P %[pays/pay] %P %s.\n", from, to, 
	      formatcash(amount, cur, 1));
}

void zone_send(const char *z, MudObject *notr, const char *t)
{
  Player *p;
  int i;
  foreach(players, p, i) 
    if (p->get_flag(FL_LOGGEDIN) && p->owner && streq(z, p->owner->get("zone"))) {
      if (notr == p->owner)
	continue;
      
      p->printf("%s\n", t);
    }
}

void mplex_choose(struct msi_player *p, int i);
void mplex_setsize(struct msi_player *p, int i, int c, int r);

void mplex_update(MudObject *room) {
  if (!room->get("lua.mplex"))
    return;

  MudObject *o;
  int i;
  foreach (room->children, o, i) {
    Player *p = dynamic_cast<Player*>(o);
    if (!p)
      continue;
    
    if (p->p && (p->p->mplex || p->p->mxp)) {
      dotrap("mplex", p, room);
    }
  }
}

void recchildren_helper(NewWorld &w, MudObject *blah) {
  w.add(*blah);
  MudObject *o;
  int i;
  foreach(blah->children, o, i)
    recchildren_helper(w, o);
}

NewWorld recchildren(MudObject *of)
{
  NewWorld w;
  MudObject *o;
  int i;
  foreach(of->children, o, i)
    recchildren_helper(w, o);
  return w;
}

NewWorld players_visible_to(MudObject *who)
{
  NewWorld w;
  MudObject *o;
  int i;
  foreach(players, o, i)
    if (visible_to(who, o))
      w.add(*o);
  return w;
}

NewWorld allplayers()
{
	NewWorld w;
	MudObject *o;
	int i;
	foreach(players,o,i)
		w.add(*o);
	return w;
}

string esc(World <MudObject> *blah)
{
  string s = "{";
  int n = 0;
  MudObject *o;
  int i;
  foreach(blah, o, i) {
    if (n == 3) {
      s += ", ...";
      break;
    }

    if (n)
      s += ", ";
    s += "\"";
    s += o->id;
    s += "\"";
    n++;
  }
  s += "}";
  return s;
}

string esc(World <MudObject> &blah)
{
  return esc(&blah);
}

string esc(const char *b)
{
  if (!b) return "nil";
  string s;
  int left = 80;
  s += "\"";
  while (*b && left) {
    if (*b=='\n') { s += "\\n"; b++; }
    else if (*b=='\\') { s += "\\\\"; b++; }
    else {
      s+= *b;
      b++;
    }
    left--;
  }
  s += "\"";
  if (*b) {
    s += "...";
  }
  return s;
}


string esc(const Table &t)
{
  string s = "{";
  for (int i=0;i<t.argc;i++) {
    if (i)
      s += ", ";
    s += esc(t.argv[i]);
  }
  s += "}";
  return s;
}

string esc(MudObject *o)
{
  if (!o)
    return "nil";
  if (o->id) {
    string s = "get(\"";
    s += o->id;
    s += "\")";
    return s;
  }
  return "???";
}

string esc(const string &s) { return esc(s.c_str()); }

void lua_pushstring(lua_State *l, const string &s) 
{
  lua_pushstring(l, s.c_str());
}

void send_room(MudObject *who, const char *txt)
{
  MudObject *o;
  int i;
  const char *n = strchr(txt, '\n')?"":"\n";
  foreach(who->children, o, i) {
    o->printf("%s%s", txt, n);
    if (who->get_flag(FL_LINKED)) {
      if (MudObject *link = linkedlink(o)) {
	MudObject *p;
	int j;
	foreach (link->children, p, j)
	  p->printf("%s%s", txt, n);
      }
    }
  }
}

void arrest(MudObject *onwho, MudObject *bywho, const char *why) 
{
  bywho->interpretf("%s %s", MUD_HELPCHAN, why);

  MudObject *coproom = find_coproom(onwho->owner);

  if (!coproom)
    return;

  MudObject *plod = choose_random_object_from(coproom->id);

  if (plod) {
    set_owner(plod, "empty");
    plod->setf("!plan", "1 goto %s;1 say %s;1 arrest %s;1 goin %s;0 summon %s;2 goto", 
	       onwho->id, 
	       lang("What's going on here then?", plod),
	       onwho->id, 
	       coproom->get("interview"),
	       onwho->id);
    
    plod->set("!when", 1);
    plod->setf("!what", "%s %s", MUD_HELPCHAN, lang("On my way.", plod));
    plod->set_bflag(FL_TIMER, 1);
    plod->set_bflag(FL_REFUSEMOVE, 1);
  }
}

#include "autohook.h"


void autodefine(lua_State *L) {
  AUTODEFINE
}