TinyMAZE/
TinyMAZE/config/
TinyMAZE/doc/
TinyMAZE/run/msgs/
TinyMAZE/src/
TinyMAZE/src/db/
TinyMAZE/src/ident/
TinyMAZE/src/io/
TinyMAZE/src/prog/
TinyMAZE/src/softcode/
TinyMAZE/src/util/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "db.h"
#include "config.h"
#include "credits.h"
#include "externs.h"

void do_destroy(OBJ *player, char *name)
{
  OBJ *thing;
  char tname[1024];

  if(!(thing = match_object(player, name, NOTYPE)))
  {
    notify(player, no_match(name));
    return;
  }

  if(!controls(player, thing, POW_MODIFY))
  {
    notify(player, perm_denied());
    return;
  }

  if(thing == player_start_obj || thing == root_obj)
  {
    notify(player, tprintf("%s is not destroyable.",
      unparse_object(player, thing)));
    return;
  }

  if(Typeof(thing) == TYPE_PLAYER)
  {
    notify(player, "Use @nuke to destroy players.");
    return;
  }

  strcpy(tname, unparse_object(player, thing));

  destroy_obj(thing);

  notify(player, tprintf("%s has been destroyed.", tname));
}

void destroy_obj(OBJ *obj)
{
  OBJ *o, *oprev = NULL, **list = NULL;

  plugin_destroy(obj);

  if(Typeof(obj) != TYPE_PLAYER && !(obj->flags & QUIET))
    do_pose(obj, "shakes and starts to crumble", "");
  do_halt(obj, "");

  remove_refs(obj);

  if(Typeof(obj) == TYPE_PLAYER)
  {
    stack_free(obj->pows);
    free_mail(obj);
  }

  stack_free(obj->name);

  free_progs(obj);
  atr_free(obj);

  del_event_ref(obj, NULL);
  del_event_ref(NULL, obj);

/* We have to remember to update db_list and db_top */
  if(obj->dbref == db_top-1)
  {
    while(!db_list[(--db_top)-1]);  /* Whole loop */
    db_list = (OBJ **)stack_realloc(db_list, sizeof(OBJ *)*db_top);
  }
  else
    db_list[obj->dbref] = NULL;

/* Remove the object from the proper list */
  switch(Typeof(obj))
  {
    case TYPE_PLAYER: list = &player_list; break;
    case TYPE_ROOM:   list = &room_list;   break;
    case TYPE_THING:  list = &thing_list;  break;
    case TYPE_EXIT:   list = &exit_list;   break;
  }

  for(o = *list;o;o = o->next)
  {
    if(o == obj)
      break;
    oprev = o;
  }

  if(oprev)
    oprev->next = o->next;
  else
    *list = o->next;

  stack_free(obj);
}

static void calc_memstats()
{
  OBJ *o;
  int mem = 0;
  char buf[1024];

  for(o = player_list;o;o = o->next)
    mem += mem_usage(o);
  for(o = thing_list;o;o = o->next)
    mem += mem_usage(o);
  for(o = room_list;o;o = o->next)
    mem += mem_usage(o);
  for(o = exit_list;o;o = o->next)
    mem += mem_usage(o);

  sprintf(buf, "%d", mem);

  com_send("dbinfo", NULL,
    tprintf("* There are %s bytes being used in memory, total.",
    comma(buf)));
}

void do_dbck(OBJ *player)
{
  if(!power(player, POW_DB))
  {
    notify(player, perm_denied());
    return;
  }

  calc_memstats();
}

void do_disconnected(OBJ *player, char *arg)
{
  OBJ *o, *p;
  int type;
  int nrooms = 0, nexits = 0;

  if(!*arg)
    type = 2;
  else if(!string_compare(arg, "rooms"))
    type = 1;
  else if(!string_compare(arg, "exits"))
    type = 0;
  else
  {
    notify(player, "Usage: @disconnected [rooms|exits]");
    return;
  }

  if(type == 1 || type == 2)
  {
    for(o = room_list;o;o = o->next)
    {
      if(!controls(player, o, POW_EXAMINE))
        continue;

      for(p = exit_list;p;p = p->next)
      {
        if(p->link == o)
          break;
      }

      if(p)
        continue;

      if(!nrooms++)
        notify(player, "|+C|Disconnected Rooms|+W|:");

      notify(player, tprintf("  %s is disconnected. |+W|%s",
        unparse_object(player, o),
        (IS(o, TYPE_ROOM, ROOM_FLOATING))?"(FLOATING)":""));
    }

    if(!nrooms)
      notify(player, "|+B|There are no disconnected rooms.");
    else
    {
      if(nrooms == 1)
        notify(player, "|+B|There is |+W|1|+B| disconnected room.");
      else
        notify(player,
          tprintf("|+B|There are |+W|%d|+B| disconnected rooms.", nrooms));
    }
  }

  if(type == 0 || type == 2)
  {
    for(o = exit_list;o;o = o->next)
    {
      if(!controls(player, o, POW_EXAMINE))
        continue;

      if(o->link)
        continue;

      if(!nexits++)
        notify(player, "|+C|Disconnected Exits|+W|:");

      notify(player, tprintf("  %s is disconnected.",
        unparse_object(player, o)));
    }

    if(!nexits)
      notify(player, "|+B|There are no disconnected exits.");
    else
    {
      if(nexits == 1)
        notify(player, "|+B|There is |+W|1|+B| disconnected exit.");
      else
        notify(player,
          tprintf("|+B|There are |+W|%d|+B| disconnected exits.", nexits));
    }
  }
}

int mem_usage(OBJ *thing)
{
  int k;
  ALIST *atr;

  k = sizeof(OBJ);
  k += strlen(thing->name)+1;
  for(atr = thing->attrlist;atr;atr = atr->next)
  {
    if(atr->attr->flags & AF_NOMEM)
      continue;
    k += sizeof(ALIST);
    k += strlen(atr->value)+1;
  }

  return(k);
}