/
teeny/db/
teeny/dbm/
teeny/docs/
teeny/includes/
teeny/misc/
teeny/news/
teeny/text/
/* cmds.c */

#include "copyright.h"
#include "config.h"

#include <stdio.h>
#ifdef STRING_H
#include <string.h>
#else
#include <strings.h>
#endif                                  /* STRING_H */
#include <ctype.h>

#include "teeny.h"
#include "match.h"
#include "db.h"

/*
 * These routines, together with those in buildcmds.c, wiz.c and speech.c
 * actually implement the commands of TeenyMUD. Hrm. Actually WHO and QUIT
 * are caught in the network interface code. 
 */

/*
 * Workspace for building strings. None of this sprintf() shit. A little
 * extra space so we can be non-anal about counting. 
 */

char            cmdwork[BUFFSIZ + 16];

char		poll[36];	/* Poll for the @doing command */

void 
do_home(player)
  int             player;
{
  int             here, home, list, count, next;
  char           *name, *p;

  if (get_int_elt(player, HOME, &home) == -1)
    goto homebomb;
  if (!exists_object(home))
  {
    notify_player(player, "Your home does not exist!\r\n");
    home = STARTING_LOC;
  }
  if (get_int_elt(player, LOC, &here) == -1)
    goto homebomb;

  /* Tell people here. */

  if (get_str_elt(player, NAME, &name) == -1)
    goto homebomb;
  p = cmdwork;
  if (name != NULL)
  {
    for (count = 0; !isspace(*name) && *name && count < BUFFSIZ; count++)
    {
      *p++ = *name++;
    }
  }

  if (!isdark(here) && !isdark(player))
  {
    strcpy(p, " goes home.\r\n");
    notify_oall(player, cmdwork);
    strcpy(p, " has left.\r\n");
    notify_oall(player, cmdwork);
  }
  send_home(player, here);

  flush_room(here);

  if (!isdark(player) && !isdark(home))
  {
    strcpy(p, " has arrived.\r\n");
    notify_oall(player, cmdwork);
  }
  /* Send all the player's stuff home too */

  if (get_int_elt(player, CONTENTS, &list) == -1)
    goto homebomb;
  while (list != -1)
  {
    /* send_home() will change the NEXT element of list */

    if (get_int_elt(list, NEXT, &next) == -1)
      goto homebomb;
    send_home(list, player);
    list = next;
  }
  /* Tell the player */

  notify_player(player, "There's no place like home...\r\n");
  notify_player(player, "There's no place like home...\r\n");
  notify_player(player, "There's no place like home...\r\n");
  notify_player(player, "You wake up back home, without your possessions.\r\n");

  do_look(player, (char *) NULL);
  return;

homebomb:

  notify_bad(player);
  return;
}

voidfunc 
do_drop(player, arg)
  int             player;
  char           *arg;
{
  int             here, obj, flags, i, dest, hereflags;
  char           *p, *q, *name;

#ifdef DROP_FIELDS
  char           *drop, *odrop;

#endif				/* DROP_FIELDS */

  if (!arg || !*arg)
  {
    notify_player(player, "Drop what?\r\n");
    return;
  }
  if ((obj = match_here(player, player, arg, MAT_THINGS)) == -1)
  {
    if ((obj = match_here(player, player, arg, MAT_EXITS)) == -1)
    {
      notify_player(player, "You don't have that!\r\n");
      return;
    }
  }
  if (obj == -2)
  {
    notify_player(player, "I can't tell which one you want to drop.\r\n");
    return;
  }
  if (get_int_elt(obj, FLAGS, &flags) == -1)
    goto dropbomb;
  if (get_int_elt(player, LOC, &here) == -1)
    goto dropbomb;

  switch (flags & TYPE_MASK)
  {
  case TYP_EXIT:
#ifndef BUILDING_OK
    if (!controls(player, here))
    {
      notify_player(player, "You can't drop that here!\r\n");
      return;
    }
#else
    if (!controls(player, here) && !isbuilder(here))
    {
      notify_player(player, "You can't drop that here!\r\n");
      return;
    }
#endif				/* BUILDING_OK */
    /* Drop from player exits, add to room exits */

    list_drop(obj, player, 0);	/* 0 == exits list */
    list_add(obj, here, 0);
    dest = here;		/* For setting the LOC later */
#ifdef TIMESTAMPS
    stamp(obj);
#endif
    break;
  case TYP_THING:
    /* Figure out where it's supposed to go */

    if (get_int_elt(here, FLAGS, &hereflags) == -1)
      goto dropbomb;

    if ((flags & STICKY) || (hereflags & TEMPLE))
    {

      /* If the object is STICKY, or this is a temple */
      /* Send the object to home if you can.     */

      if (get_int_elt(obj, HOME, &dest) == -1)
	goto dropbomb;

    } else
    if (!(hereflags & STICKY))
    {

      /* If this place is !STICKY, see if there's a dropto */

      if (get_int_elt(here, DROPTO, &dest) == -1)
	goto dropbomb;

      if (dest == -1)
      {				/* No dropto */
	dest = here;
      } else
      if (dest == -3)
      {				/* Dropto home */
	if (get_int_elt(obj, HOME, &dest) == -1)
	  goto dropbomb;
      }
    } else
    {
      dest = here;
    }
    list_drop(obj, player, 1);	/* 1 == contents list */
    list_add(obj, dest, 1);

#ifdef TIMESTAMPS
    stamp(obj);
#endif

    /* Tell the room */

#ifndef DROP_FIELDS
    if (get_str_elt(player, NAME, &name) == -1)
      goto dropbomb;
    p = cmdwork;
    if (name != NULL)
    {
      for (i = 0; !isspace(*name) && *name
	   && i < BUFFSIZ - 128; i++)
      {
	*p++ = *name++;
      }
    }
    strcpy(p, " dropped ");
    p += 9;
    i += 9;
    if (get_str_elt(obj, NAME, &name) == -1)
      goto dropbomb;
    if (name != NULL)
    {
      for (q = name; *q && i < BUFFSIZ - 4; i++)
      {
	*p++ = *q++;
      }
    }
    *p++ = '.';
    *p++ = '\r';
    *p++ = '\n';
    *p = '\0';
    notify_oall(player, cmdwork);
#else
    if (get_str_elt(obj, DROP, &drop) == -1)
      goto dropbomb;
    if (drop != NULL)
    {
      notify_player(player, drop);
      notify_player(player, "\r\n");
    }
    if (get_str_elt(player, NAME, &name) == -1)
      goto dropbomb;
    if (get_str_elt(obj, ODROP, &odrop) == -1)
      goto dropbomb;
    p = cmdwork;
    if (name != NULL)
    {
      for (i = 0; !isspace(*name) && *name
	   && i < BUFFSIZ - 128; i++)
      {
	*p++ = *name++;
      }
    }
    if (odrop != NULL)
    {
      char           *sub;

      sub = pronoun_sub(player, odrop);
      *p++ = ' ';
      i++;
      for (; sub && *sub && i < BUFFSIZ - 2; i++)
	*p++ = *sub++;
      if (get_str_elt(obj, NAME, &name) == -1)
	goto dropbomb;
    } else
    {
      strcpy(p, " dropped ");
      p += 9;
      i += 9;
      if (get_str_elt(obj, NAME, &name) == -1)
	goto dropbomb;
      if (name != NULL)
      {
	for (q = name; *q && i < BUFFSIZ - 3; i++)
	{
	  *p++ = *q++;
	}
      }
      *p++ = '.';
    }
    *p++ = '\r';
    *p++ = '\n';
    *p = '\0';
    notify_oall(player, cmdwork);

    if (dest != here)
    {
      p = cmdwork;
      q = name;
      if (name != NULL)
      {
	while (*q && (p - cmdwork) < BUFFSIZ)
	  *p++ = *q++;
	*p++ = ' ';
	if (get_str_elt(here, ODROP, &odrop) == -1)
	  goto dropbomb;
	if (odrop != NULL)
	{
	  while (*odrop && (p - cmdwork) < BUFFSIZ - 3)
	    *p++ = *odrop++;
	  *p++ = '\r';
	  *p++ = '\n';
	  *p++ = '\0';
	  notify_all(player, cmdwork);
	}
      }
    }
#endif				/* DROP_FIELDS */

    break;
  default:
    notify_player(player, "You have no business carrying that!\r\n");
    return;
  }
  if (set_int_elt(obj, LOC, dest) == -1)
    goto dropbomb;
  notify_player(player, "Dropped.\r\n");
  return;
dropbomb:
  notify_bad(player);
  return;
}

#ifdef VERBOSE_FLAGS
static char    *
display_flags(obj)
  int             obj;
{
  static char     buffer[1024];
  int             flags;

  if (get_int_elt(obj, FLAGS, &flags) == -1)
  {
    strcpy(buffer, "<spammed flags>");
    return buffer;
  } else
  {
    strcpy(buffer, "Type: ");
    switch (flags & TYPE_MASK)
    {
    case TYP_ROOM:
      strcat(buffer, "Room");
      break;
    case TYP_EXIT:
      strcat(buffer, "Exit");
      break;
    case TYP_PLAYER:
      strcat(buffer, "Player");
      break;
    case TYP_THING:
      strcat(buffer, "Thing");
      break;
    default:
      strcat(buffer, "*UNKNOWN TYPE*");
    }
    if (flags & ~(TYPE_MASK | INTERNAL_FLAGS))
    {
      strcat(buffer, "  Flags: ");
      if (flags & WIZARD)
	strcat(buffer, "WIZARD ");
      if (flags & TEMPLE)
      {
        if((flags & TYPE_MASK) != TYP_PLAYER)
	  strcat(buffer, "TEMPLE ");
        else
	  strcat(buffer, "TEMPORAL ");
      }
      if (flags & STICKY)
	strcat(buffer, "STICKY ");
      if (flags & LINK_OK)
	strcat(buffer, "LINK_OK ");
      if (flags & JUMP_OK)
	strcat(buffer, "JUMP_OK ");
      if (flags & ABODE)
	strcat(buffer, "ABODE ");
      if (flags & HAVEN)
      {
        if((flags & TYPE_MASK) != TYP_PLAYER)
	  strcat(buffer, "HAVEN ");
        else
	  strcat(buffer, "HURIN ");
      }
      if (flags & DARK)
	strcat(buffer, "DARK ");
#ifdef BUILDING_OK
      if (flags & BUILDER)
      {
        if((flags & TYPE_MASK) != TYP_PLAYER)
	  strcat(buffer, "BUILDING_OK ");
        else
	  strcat(buffer, "BUILDER ");
      }
#else
      if (flags & BUILDER)
	strcat(buffer, "BUILDER ");
#endif				/* BUILDING_OK */
    }
    return buffer;
  }
}

#endif				/* VERBOSE_FLAGS */
voidfunc 
do_examine(player, arg)
  int             player;
  char           *arg;
{
  int             obj, loc1, loc2, num, len, flags;
  int            *lock;
  char           *p, *msg;

  if (!arg || !*arg)
  {
    if (get_int_elt(player, LOC, &obj) == -1)
      goto exbomb;
  } else
  {
    if ((obj = resolve_anything(player, arg, 0)) == -1)
    {
      notify_player(player, "I can't find that.\r\n");
      return;
    }
    if (obj == -2)
    {
      notify_player(player, "I can't tell which one you mean.\r\n");
      return;
    }
  }
  if (!exists_object(obj))
  {
    notify_player(player, "No such object.\r\n");
    return;
  }
  if (!controls(player, obj)
#ifdef ABODE_EXAMINE
      && !isabode(obj)
#endif				/* ABODE_EXAMINE */
      )
  {
    if (get_int_elt(player, LOC, &loc1) == -1)
      goto exbomb;
    if (get_int_elt(obj, LOC, &loc2) == -1)
      goto exbomb;
    if (obj == loc1)
      do_look(player, (char *) NULL);
    if (player == loc2 || loc1 == loc2)
      do_look(player, arg);
    /* Owner */
    if (get_int_elt(obj, OWNER, &num) == -1)
      goto exbomb;
    if ((len = stuff_name(player, num, cmdwork, BUFFSIZ)) == -1)
    {
      strcpy(cmdwork, "<spammed name>");
    } else
    {
      cmdwork[len] = '\0';
    }
    notify_player(player, "Owner: ");
    notify_player(player, cmdwork);
    notify_player(player, "\r\n");
    return;
  }
  if (get_int_elt(obj, FLAGS, &flags) == -1)
    goto exbomb;

  /* OK. Get this things data, and print it out! */
  /* name */
  if ((len = stuff_name(player, obj, cmdwork, BUFFSIZ)) == -1)
  {
    strcpy(cmdwork, "<spammed name>");
  } else
  {
    cmdwork[len] = '\0';
  }
  notify_player(player, cmdwork);
  notify_player(player, "\r\n");

  /* Owner */

  if (get_int_elt(obj, OWNER, &num) == -1)
    goto exbomb;
  if ((len = stuff_name(player, num, cmdwork, BUFFSIZ)) == -1)
  {
    strcpy(cmdwork, "<spammed name>");
  } else
  {
    cmdwork[len] = '\0';
  }
  notify_player(player, "Owner: ");
  notify_player(player, cmdwork);

  if (get_lock_elt(obj, LOCK, &lock) == -1)
    goto exbomb;
  notify_player(player, "  Key: ");
  if (bool_display(player, lock, cmdwork, BUFFSIZ) == -1)
  {
    notify_player(player, "Bad lock.");
  } else
  {
    notify_player(player, cmdwork);
  }

  if (isplayer(obj))
  {
    if (get_int_elt(obj, SITE, &num) == -1)
      goto exbomb;
#ifndef BACKWARDS_IP
    sprintf(cmdwork, "  Site: %d.%d.%d.%d\r\n", (num >> 24) & 0xff,
        (num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff);
#else
    sprintf(cmdwork, "  Site: %d.%d.%d.%d\r\n", num & 0xff, (num >> 8) & 0xff,
        (num >> 16) & 0xff, (num >> 24) & 0xff);
#endif
    notify_player(player, cmdwork);
  } else
  {
    notify_player(player, "\r\n");
  }

#ifdef VERBOSE_FLAGS
  notify_player(player, display_flags(obj));
  notify_player(player, "\r\n");
#endif				/* VERBOSE_FLAGS */

#ifdef TIMESTAMPS
  {
    extern char    *ctime();
    long            timestamp;
    char            temp[30], *ti;

    if (get_int_elt(obj, TIMESTAMP, &num) == -1)
      goto exbomb;
    timestamp = (long) (num * 60);
    if (isplayer(obj))
      notify_player(player, "Last: ");
    else
      notify_player(player, "Timestamp: ");

    ti = ctime(&timestamp);
    ti[24] = '\0';		/* make one break here */
    ti[16] = '\0';		/* and another here */
    (void) strcpy(temp, ti);	/* chainsaw, please */
    (void) strcat(temp, ti + 19);
    (void) strcat(temp, "\r\n");

    notify_player(player, temp);
  }
#endif				/* TIMESTAMPS */

  /* desc */
  if (get_str_elt(obj, DESC, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
  /* fail, succ, etc.. */
  if (get_str_elt(obj, FAIL, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    if(isplayer(obj))
      notify_player(player, "Oarrive: ");
    else
      notify_player(player, "Fail: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
  if (get_str_elt(obj, SUC, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    if(isplayer(obj))
      notify_player(player, "Oleave: ");
    else
      notify_player(player, "Success: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
#ifdef DROP_FIELDS
  if (get_str_elt(obj, DROP, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, "Drop: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
#endif				/* DROP_FIELDS */
  if (get_str_elt(obj, OFAIL, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, "Ofail: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
  if (get_str_elt(obj, OSUC, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, "Osuccess: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
#ifdef DROP_FIELDS
  if (get_str_elt(obj, ODROP, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, "Odrop: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
#endif				/* DROP_FIELDS */
  if (get_str_elt(obj, GENDER, &p) == -1)
    goto exbomb;
  if (p != NULL)
  {
    notify_player(player, "Sex: ");
    notify_player(player, p);
    notify_player(player, "\r\n");
  }
  /* home NOTE: Home == DropTo == Dest, depending on object type */
  if (get_int_elt(obj, HOME, &num) == -1)
    goto exbomb;
  switch (flags & TYPE_MASK)
  {
  case TYP_ROOM:
    notify_player(player, "Dropto: ");
    if (num == -3)
      msg = "*HOME*\r\n";
    else
      msg = "None.\r\n";
    break;
  case TYP_EXIT:
    notify_player(player, "Destination: ");
    if (num == -3)
      msg = "*HOME*\r\n";
    else
      msg = "*UNLINKED*\r\n";
    break;
  case TYP_THING:
  case TYP_PLAYER:
    notify_player(player, "Home: ");
    msg = "Does not exist!\r\n";
    break;
  }
  if (exists_object(num))
  {
    if ((len = stuff_name(player, num, cmdwork, BUFFSIZ)) == -1)
    {
      strcpy(cmdwork, "<spammed name>");
    } else
    {
      cmdwork[len] = '\0';
    }
    notify_player(player, cmdwork);
    notify_player(player, "\r\n");
  } else
  {
    notify_player(player, msg);
  }
  /* location */

  if ((flags & TYPE_MASK) != TYP_ROOM)
  {
    if (get_int_elt(obj, LOC, &num) == -1)
      goto exbomb;
    if (!(!exists_object(num) && isexit(obj)) && (controls(player, num)
						  || islinkok(num)))
    {
      notify_player(player, "Location: ");
      if (exists_object(num))
      {
	if ((len = stuff_name(player, num, cmdwork, BUFFSIZ)) == -1)
	{
	  strcpy(cmdwork, "<spammed name>");
	} else
	{
	  cmdwork[len] = '\0';
	}
	notify_player(player, cmdwork);
	notify_player(player, "\r\n");
      } else
      {
	notify_player(player,
		      "Location does not exist! Obj number: ");
	if (num < 0)
	{
	  notify_player(player, "-");
	  num = -num;
	}
	p = ty_itoa(cmdwork, num);
	*p++ = '\r';
	*p++ = '\n';
	*p = '\0';
	notify_player(player, cmdwork);
      }
    }
  }
  if (!isexit(obj))
  {
    /* contents list */
    if (get_int_elt(obj, CONTENTS, &num) == -1)
      goto exbomb;
    if (num != -1)
    {
      if (!isplayer(obj))
      {
	notify_player(player, "Contents:\r\n");
      } else
      {
	notify_player(player, "Carrying:\r\n");
      }
      /* last arg == 1 == show dark objects. */
      notify_list(player, num, cmdwork, BUFFSIZ, 1);
    } else
    {
      notify_player(player, "No contents.\r\n");
    }
    /* exits list */
    if (get_int_elt(obj, EXITS, &num) == -1)
      goto exbomb;
    if (num != -1)
    {
      notify_player(player, "Exits:\n");
      /* last arg == 1 == show dark objects */
      notify_list(player, num, cmdwork, BUFFSIZ, 1);
    } else
    {
      notify_player(player, "No exits.\r\n");
    }
  }
  return;
exbomb:
  notify_bad(player);
  return;
}

voidfunc 
do_take(player, arg)
  int             player;
  char           *arg;
{
  int             here, obj, flags, dest;

  if (!arg || !*arg)
  {
    notify_player(player, "Take what?\r\n");
    return;
  }
  if (get_int_elt(player, LOC, &here) == -1)
    goto takebomb;
  if ((obj = match_here(player, here, arg, MAT_THINGS)) == -1)
  {
    if ((obj = match_here(player, here, arg, MAT_EXITS)) == -1)
    {
      if ((obj = match_here(player, here, arg, MAT_PLAYERS)) == -1)
      {
        notify_player(player, "I don't see that here.\r\n");
        return;
      }
    }
  }
  if (obj == -2)
  {
    notify_player(player, "I can't tell which one you mean.\r\n");
    return;
  }
  if (get_int_elt(obj, FLAGS, &flags) == -1)
    goto takebomb;

  switch (flags & TYPE_MASK)
  {
  case TYP_EXIT:

    /* If it's unlinked, you can take it */

    if (get_int_elt(obj, DESTINATION, &dest) == -1)
      goto takebomb;
    if (dest != -1)
    {
      notify_player(player, "That exit is linked.\r\n");
      return;
    }
    /* Drop it from exits list here. */

    list_drop(obj, here, 0);	/* 0 == exits list */

    /* Add it to player exits list. */

    list_add(obj, player, 0);	/* 0 == exits list */
#ifdef TIMESTAMPS
    stamp(obj);
#endif
    notify_player(player, "Taken.\r\n");
    break;
  case TYP_THING:

    /* If it's unlocked, you can take it */

    if (islocked(player, obj))
    {
      fail_object(player, obj, "You can't pick that up.");
#ifdef TIMESTAMPS
      stamp(obj);
#endif
      return;
    }
    /* Do the succ/osucc */

    succeed_object(player, obj, "Taken.");

    /* Drop it from contents list here. */

    list_drop(obj, here, 1);	/* 1 == contents list */

    /* Add to player contenst list */

    list_add(obj, player, 1);	/* 1 == contents list */
#ifdef TIMESTAMPS
    stamp(obj);
#endif
    break;
  default:
    notify_player(player, "You can't take that!\r\n");
    return;
  }
  if (set_int_elt(obj, LOC, player) == -1)
    goto takebomb;
  return;
takebomb:
  notify_bad(player);
  return;
}

voidfunc 
do_go(player, arg)
  int             player;
  char           *arg;
{
  struct match   *exlist;
  int             here, list, count;

  if (!arg || !*arg)
  {
    notify_player(player, "Go where?\r\n");
    return;
  }
  if (!strcmp(arg, "home"))
  {
    do_home(player);
    return;
  }
  if (get_int_elt(player, LOC, &here) == -1)
    goto gobomb;
  if (get_int_elt(here, EXITS, &list) == -1)
    goto gobomb;

  if ((exlist = match_exits(arg, list, &count)) != NULL)
  {

    /* Ok. We have a list of exits. Cope with 'em. */

    do_go_attempt(player, here, exlist);
    return;
  } else
  {
    notify_player(player, "You can't go that way.\r\n");
  }
  return;
gobomb:
  notify_bad(player);
  return;
}
voidfunc 
do_gripe(player, gripe)
  int             player;
  char           *gripe;
{
  char           *name, *p;

  if (gripe == NULL)
  {
    notify_player(player, "What do you wish to gripe about?\r\n");
    return;
  }
  if (get_str_elt(player, NAME, &name) == -1)
    goto gripebomb;

  p = cmdwork;
  while (!isspace(*name) && *name)
    *p++ = *name++;
  *p = '\0';

  log_gripe("GRIPE: From %s(#%d), \"%s\"\n", cmdwork, player, gripe);

  if (!issticky(GOD))
  {
    notify_player(GOD, "GRIPE: From ");
    notify_player(GOD, cmdwork);
    notify_player(GOD, ", \"");
    notify_player(GOD, gripe);
    notify_player(GOD, "\"\r\n");
  }

  notify_player(player, "Your complaint has been duly noted.\r\n");
  return;
gripebomb:
  notify_bad(player);
  return;

}
voidfunc 
do_inventory(player)
  int             player;
{
  int             list, header;

  header = 0;
  if (get_int_elt(player, CONTENTS, &list) == -1)
    goto invbomb;

  if (list != -1)
  {
    notify_player(player, "You are carrying:\r\n");
    header = 1;
    notify_list(player, list, cmdwork, BUFFSIZ, 1);
  }
  if (get_int_elt(player, EXITS, &list) == -1)
    goto invbomb;

  if (list != -1)
  {
    if (!header)
    {
      notify_player(player, "You are carrying:\r\n");
      header = 1;
    }
    notify_list(player, list, cmdwork, BUFFSIZ, 1);
  }
  if (!header)
    notify_player(player, "You aren't carrying anything.\r\n");
  return;
invbomb:
  notify_bad(player);
  return;
}
voidfunc 
do_kill(player, argone)
  int             player;
  char           *argone;
{
  int             here, victim, flags;
  int             list, next;
  char           *name, *p, *q, *r;

  if (!argone || !*argone)
  {
    notify_player(player, "Who would you like to kill?\r\n");
    return;
  }
  if (ishaven(player))
  {
    notify_player(player, "You may not kill anyone.\r\n");
    return;
  }
  /* Find who we are supposed to kill */

  if (get_int_elt(player, LOC, &here) == -1)
    goto killbomb;
  if (ishaven(here) && !iswiz(player))
  {
    notify_player(player, "It's too peaceful here.\r\n");
    return;
  }
  if ((victim = match_here(player, here, argone, MAT_PLAYERS)) == -1)
  {
    notify_player(player, "I don't see that player here.\r\n");
    return;
  }
  if (victim == -2)
  {
    notify_player(player, "I can't tell which person you want to kill.\r\n");
    return;
  }

  /* Grab the killer-dude's name, and stow it away. We'll want it */

  if (get_str_elt(player, NAME, &name) == -1)
    goto killbomb;
  p = cmdwork;
  if (name != NULL)
  {
    while (!isspace(*name) && *name)
    {
      *p++ = *name++;
    }
  }
  *p = '\0';

  /* Have a whack at it. */

  if (get_int_elt(victim, FLAGS, &flags) == -1)
    goto killbomb;
  if (flags & WIZARD)
  {
    /* Fail the kill */

    notify_player(player, "Your kill attempt failed.\n");
    notify_player(victim, cmdwork);
    notify_player(victim, " tried to kill you!\n");
  } else
  {
    /* The kill succeeded! Do it! */

#ifdef DROP_FIELDS
    char           *drop, *odrop;

#endif				/* DROP_FIELDS */

    notify_player(victim, cmdwork);
    notify_player(victim, " killed you!\r\n");

    /* Tell everyone. p cleverly points at the right spot  */
    /* No need to count. names are guaranteed pretty short */

#ifndef DROP_FIELDS
    strcpy(p, " killed ");
    q = p + 8;
    if (get_str_elt(victim, NAME, &name) == -1)
      goto killbomb;
    r = name;
    while (!isspace(*r) && *r)
      *q++ = *r++;
    strcpy(q, "!\r\n");

    notify_oall(victim, cmdwork);

#else
    if (get_str_elt(victim, DROP, &drop) == -1)
      goto killbomb;
    if (drop != NULL)
    {
      notify_player(player, drop);
      notify_player(player, "\r\n");
    }
    if (get_str_elt(victim, ODROP, &odrop) == -1)
      goto killbomb;
    if (odrop != NULL)
    {
      char           *sub, *pname;

      if (get_str_elt(victim, NAME, &name) == -1)
	goto killbomb;
      if (get_str_elt(player, NAME, &pname) == -1)
	goto killbomb;
      sub = pronoun_sub(player, odrop);
      strcpy(p, " killed ");
      q = p + 8;
      r = name;
      while (!isspace(*r) && *r)
	*q++ = *r++;
      strcpy(q, "!  ");
      q += 3;
      while (sub && *sub && (q - cmdwork) < BUFFSIZ - 3)
	*q++ = *sub++;
      *q++ = '\r';
      *q++ = '\n';
      *q = '\0';

      notify_oall(victim, cmdwork);
    } else
    {
      strcpy(p, " killed ");
      q = p + 8;
      if (get_str_elt(victim, NAME, &name) == -1)
	goto killbomb;
      r = name;
      while (!isspace(*r) && *r)
	*q++ = *r++;
      strcpy(q, "!\r\n");

      notify_oall(victim, cmdwork);
    }
#endif				/* DROP_FIELDS */

    p = cmdwork;
    r = name;
    while (!isspace(*r) && *r)
      *p++ = *r++;
    strcpy(p, " has left.\r\n");
    notify_oall(victim, cmdwork);

    /* Send the victim home. */

    send_home(victim, here);
    strcpy(p, " has arrived.\r\n");
    notify_oall(victim, cmdwork);

    flush_room(here);

    /* Send all the player's stuff home too */

    if (get_int_elt(victim, CONTENTS, &list) == -1)
      goto killbomb;
    while (list != -1)
    {

      /* send_home() will change the NEXT element of list */

      if (get_int_elt(list, NEXT, &next) == -1)
	goto killbomb;
      send_home(list, victim);
      list = next;
    }
    do_look(victim, (char *) NULL);

  }
  return;
killbomb:
  notify_bad(player);
  return;
}
voidfunc 
do_look(player, arg)
  int             player;
  char           *arg;
{
  int             here, contents, len;
  int             obj, loc;
  char           *str;

  if (arg && *arg)
  {

    /* Look at a thing. */

    if (get_int_elt(player, LOC, &here) == -1)
      goto lookbomb;
    if ((obj = resolve_object_or_exit(player, arg, iswiz(player))) == -1)
    {
      notify_player(player, "I don't see that here.\r\n");
      return;
    }
    if (obj == -2)
    {
      notify_player(player, "I don't know which one you mean.\r\n");
      return;
    }
    if (obj == here)
    {
      do_look(player, (char *) NULL);
      return;
    }
    if (get_int_elt(obj, LOC, &loc) == -1)
      goto lookbomb;
    if ((loc != here && loc != player && !iswiz(player)) || isroom(obj))
    {
      notify_player(player, "That's much too far away to see.\r\n");
      return;
    }
#ifdef TIMESTAMPS
    if (!isplayer(obj))
      stamp(obj);
#endif

    if (get_str_elt(obj, DESC, &str) == -1)
      goto lookbomb;
    if (str == NULL)
    {
      str = "You see nothing special.";
    }
    notify_player(player, str);
    notify_player(player, "\r\n");

    if (get_int_elt(obj, CONTENTS, &contents) == -1)
      goto lookbomb;

    if (contents != -1)
    {
      notify_player(player, "Carrying:\r\n");

      /* last argument: 0 == No dark objs. */
      notify_list(player, contents, cmdwork, BUFFSIZ, 0);
    }
    return;
  }
  if (get_int_elt(player, LOC, &here) == -1)
    goto lookbomb;
#ifdef TIMESTAMPS
  stamp(here);
#endif

  /* Grab and show the name */

  if ((len = stuff_name(player, here, cmdwork, BUFFSIZ)) == -1)
  {
    strcpy(cmdwork, "<spammed name>");
  } else
  {
    cmdwork[len] = '\0';
  }
  notify_player(player, cmdwork);
  notify_player(player, "\r\n");

  /* The desc. */

  if (get_str_elt(here, DESC, &str) == -1)
    goto lookbomb;
  if (str != NULL)
  {
    notify_player(player, str);
    notify_player(player, "\r\n");
  }
  /* Do the room succ/osucc thing */

  if (islocked(player, here))
  {
    fail_object(player, here, (char *) NULL);
  } else
  {
    succeed_object(player, here, (char *) NULL);
  }

  /* Finally spew out the contents list, if the room is unDARK */

  if (can_see_anything(player, here))
  {
    if (get_int_elt(here, CONTENTS, &contents) == -1)
    {
      warning("do_look", "bad contents ref on room");
      notify_bad(player);
      return;
    }
    notify_player(player, "Contents:\r\n");
    /* last arg == 0 == no dark objects */
    notify_list(player, contents, cmdwork, BUFFSIZ, 0);
  }
  return;
lookbomb:
  notify_bad(player);
  return;
}

voidfunc 
do_password(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  char           *pwd, *p;

  if (!argone || !*argone || !argtwo || !*argtwo)
  {
    notify_player(player,
		  "Usage: @password <oldpassword> = <newpassword>\r\n");
    return;
  }
  if (get_str_elt(player, NAME, &pwd) == -1)
    goto passbomb;
  if (!pwd || !*pwd)
  {
    notify_player(player, "You have no name OR password!\r\n");
    return;
  }
  /* Copy the actual name into cmdwork */
  p = cmdwork;
  while (!isspace(*pwd) && *pwd)
    *p++ = *pwd++;

  /* Find the current pwd */

  while (isspace(*pwd) && *pwd)
    pwd++;

  if (strcmp(pwd, argone))
  {
    notify_player(player, "Incorrect password.\r\n");
    return;
  }
  /* OK. Set the password up in cmdwork */
  *p++ = ' ';
  while (*argtwo)
    *p++ = *argtwo++;
  *p++ = '\0';

  if (set_str_elt(player, NAME, cmdwork) == -1)
    goto passbomb;
  notify_player(player, "Password changed.\r\n");
  return;
passbomb:
  notify_bad(player);
  return;
}

voidfunc
do_poll(player, arg)
  int             player;
  char           *arg;
{
  int             i;

  if(!iswiz(player))
  {
    notify_player(player, "Having delusions of grandeur, are we?\r\n");
    return;
  }

  if(arg == NULL)
  {
    notify_player(player, "Set.\r\n");
    strcpy(poll, "");
    return;
  }
  if(strlen(arg) > 35)
  {
    notify_player(player, "Too long -- clipped.\r\n");
    arg[35] = '\0';
  } else
  {
    notify_player(player, "Set.\r\n");
  }

  strcpy(poll, arg);
  return;
}

voidfunc 
do_set(player, argone, argtwo)
  int             player;
  char           *argone, *argtwo;
{
  int             obj, unset, newflag, objflags, playerflags;
  char           *msg;

  if (!argone || !*argone || !argtwo || !*argtwo)
  {
    notify_player(player, "Set what?\r\n");
    return;
  }
  if ((obj = resolve_object_or_exit(player, argone, 0)) == -1)
  {
    notify_player(player, "I can't find what you want to set.\r\n");
    return;
  }
  if (obj == -2)
  {
    notify_player(player, "I can't tell which one you want to set.\r\n");
    return;
  }
  if (!exists_object(obj) || !controls(player, obj))
  {
    notify_player(player, "You can't set that!\r\n");
    return;
  }
#ifdef TIMESTAMPS
  if (!isplayer(obj))
    stamp(obj);
#endif

  /* Okie. What's this doof want to set? */

  if (*argtwo == '!')
  {
    unset = 1;
    argtwo++;
  } else
  {
    unset = 0;
  }
  if (stringprefix(argtwo, "LINK_OK"))
    newflag = LINK_OK;
  else
  if (stringprefix(argtwo, "STICKY"))
    newflag = STICKY;
  else
  if (stringprefix(argtwo, "DARK"))
    newflag = DARK;
  else
  if (stringprefix(argtwo, "WIZARD"))
    newflag = WIZARD;
  else
  if (stringprefix(argtwo, "TEMPLE"))
    newflag = TEMPLE;
  else
  if (stringprefix(argtwo, "TEMPORAL"))
    newflag = TEMPLE;
  else
  if (stringprefix(argtwo, "JUMP_OK"))
    newflag = JUMP_OK;
  else
  if (stringprefix(argtwo, "ABODE"))
    newflag = ABODE;
  else
  if (stringprefix(argtwo, "HAVEN"))
    newflag = HAVEN;
#if defined(RESTRICT_BUILDING) || defined(BUILDING_OK)
  else
  if (stringprefix(argtwo, "BUILDER"))
    newflag = BUILDER;
  else
  if (stringprefix(argtwo, "BUILDING_OK"))
    newflag = BUILDER;
#endif				/* RESTRICT_BUILDING || BUILDING_OK */
  else
  {
    notify_player(player, "I don't understand that flag.\r\n");
    return;
  }

  /* Check legalities */

  if (get_int_elt(player, FLAGS, &playerflags) == -1)
    goto setbomb;
  if (get_int_elt(obj, FLAGS, &objflags) == -1)
    goto setbomb;

  if (!(playerflags & WIZARD) && !isexit(obj))
  {
    if ((newflag == DARK) && (objflags & TYPE_MASK) == TYP_PLAYER)
    {
      notify_player(player, "Permission denied.\r\n");
      return;
    }
    if ((newflag == HAVEN || newflag == BUILDER)
	&& (objflags & TYPE_MASK) != TYP_ROOM)
    {
      notify_player(player, "Permission denied.\r\n");
      return;
    } else
    if (newflag == TEMPLE)
    {
      notify_player(player, "Permission denied.\r\n");
      return;
    }
  }
  if (newflag == WIZARD && player != GOD)
  {
    notify_player(player, "Permission denied.\r\n");
    return;
  }
  /* Set the flags */

  if (unset)
  {
    objflags &= ~newflag;
    msg = "Flag unset.\r\n";
  } else
  {
    objflags |= newflag;
    msg = "Flag set.\r\n";
  }
  if (set_int_elt(obj, FLAGS, objflags) == -1)
    goto setbomb;
  notify_player(player, msg);

  return;
setbomb:
  notify_bad(player);
  return;
}
voidfunc 
do_recycle(player, arg)
  int             player;
  char           *arg;
{
  int             obj, loc;

  if (!arg || !*arg)
  {
    notify_player(player, "Recycle what?\r\n");
    return;
  }
  if (get_int_elt(player, LOC, &loc) == -1)
  {
    warning("do_recycle", "bad loc ref on player");
    return;
  }
  if ((obj = match_here(player, player, arg, MAT_THINGS | MAT_EXITS)) == -1)
  {
    if ((obj = match_here(player, loc, arg, MAT_THINGS | MAT_EXITS)) == -1)
    {
      if (!strcmp(arg, "here"))
      {
	obj = loc;
      } else
      {
	if (*arg == '#' && *(arg + 1) && exists_object(atoi(arg + 1)))
	{
	  obj = atoi(arg + 1);
	} else
	{
	  notify_player(player, "I can't find what you want to recycle.\r\n");
	  return;
	}
      }
    }
  }
  if (obj == -2)
  {
    notify_player(player, "I can't tell which one you want to recycle.\r\n");
    return;
  }
  if (!controls(player, obj))
  {
    notify_player(player, "You don't own that!\r\n");
    return;
  }
  if (obj == 0)
  {
    notify_player(player, "You may not recycle object Zero.\r\n");
    return;
  }
#if STARTING_LOC != 0
  if (obj == STARTING_LOC)
  {
    notify_player(player, "You may not recycle that.\r\n");
    return;
  }
#endif

  if (isplayer(obj))
  {
    notify_player(player, "You can't recycle players.\r\n");
    return;
  }
  if (recycleobj(obj) > 0)
  {
    notify_player(player, "Thank you for recycling.\r\n");
  } else
  {
    notify_bad(player);
  }
}
voidfunc 
do_version(player)
  int             player;
{
  notify_player(player, "The code running is ");
  notify_player(player, version);
  notify_player(player, ".\r\n");
}