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/
/* 
 * MusicMUD - Player Customisation Module
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */
#include <ctype.h>

#include "musicmud.h"
#include "util.h"
#include "verbs.h"
#include "State.h"
#include "Player.h"
#include "misc.h"
#include "flagnames.h"
#include "pflags.h"
#include "pflagnames.h"
#include "colour.h"
#include "prep.h"
#include "msi.h"

#include <list>
#include <algorithm>

#define MODULE "custom"

static bool verb_prompt(MudObject *player, int argc, const char **argv) {
     if (argc < 2) {
       player->printf("syntax : prompt what\n");
       return true;
       return true;
      }
    string rest = the_rest(argc, argv, 1);
    char temp[4096];
    if (rest[0]=='!') 
      temp[0]=0;
    else
      strcpy(temp, rest.c_str());
    if (streq(argv[1], "\\")) {
      player->unset("prompt.cmd");
    } else {
      player->set("prompt.cmd", temp);
    }
    player->printf("Prompt set.\n");
    return true;
}



static bool verb_nametransplant(MudObject *who, int argc, const char **argv) {
  if (argc < 3) {
    who->printf("nametransplant <oldname> <newname>\n");
    return true;
  }
  MudObject *what = get_player(who, argv[1]);
  if (!is_player(what)) {
    who->printf("You may only give a name transplant to a player.\n");
    return true;
  }
  if (what!=who && !IS_ADMIRAL(who)) {
    who->printf("You are not powerful enough.\n");
    return true;
  }
  if (!IS_CAPTAIN(who)) {
    who->printf("You are not powerful enough.\n");
    return true;
  }
  if (player_exist(argv[2])) {
    who->printf("Name already in use.\n");
    return true;
  }
  {
    Object *target = planet->get(argv[2]);
    if (!target) target = verbs->get(argv[2]);
    if (target) {
      who->printf("That name is already in use.\n");
      return true;
    }
  }

  string newshort = argv[2];
  newshort[0] = toupper(newshort[0]);
  string newlong = "^p";
  newlong += newshort;
  newlong += "^n";
  string newid = argv[2];
  for (unsigned int i=0;i<newid.length();i++) {
    newid[i] = tolower(newid[i]);
  }

  what->set("id", newid.c_str());
  what->set("short", newid.c_str());
  what->set("name", newlong.c_str());
  what->interpret("save");

  return true;
}

static bool verb_homeroom(MudObject *player, int argc, const char **argv) {
    if (argc < 2) {
	const char *s = player->get("start");
	if (s) {
	    player->printf("Your homeroom is %s.\n", s);
	    if (!planet->get(s)) {
	      player->printf("That location does not exist - you should set your homeroom to something that does.\n", s);
	    }
	}
	else 
	    player->printf("You haven't set a homeroom.\n");
	return true;
    }
    if (streq(argv[1], "here")) {
      player->set("start", player->owner->id);
      return true;
    }
    if (!planet->get(argv[1])) {
      player->printf("No such location as %s\n", argv[1]);
      return true;
    }
    player->set("start", argv[1]);
    return true;
}

struct {
    const char *cmd;
    const char *id;
  const char *synt;
} setfinger[] = {
	{ "email", "finger.email", "<address>" },
	{ "irlname", "finger.name", "<name>" },
	{ "url", "finger.url", "<address>" },
	{ "uin", "finger.uin", "<number>" },
	{ "phone", "finger.phone", "<number>" },
	{ "dob", "finger.dob", "yyyy-mm-dd" },
};

#define ELEMENTS(a) (int)(sizeof(a)/sizeof(a[0]))

static bool verb_setfinger(MudObject *player, int argc, const char **argv) {
    if (argc < 2) {
      for (int i=0;i<ELEMENTS(setfinger);i++) {
	if (streq(setfinger[i].cmd, argv[0])) {
	  player->printf("%s %s\n", argv[0], setfinger[i].synt);
	}
      }
      return true;
    }

    string text = the_rest(argc, argv, 1);

    if ((text == "erase") || (text == "none") ||
        (text == "off") || (text == "delete")) {
      for (int i=0;i<ELEMENTS(setfinger);i++) {
	if (streq(setfinger[i].cmd, argv[0])) {
	  player->unset(setfinger[i].id);
	  player->printf("OK.\n");
	  return true;
	}
      }
      return true;
    }

    if (streq(argv[0], "dob")) {
      if (text.length()!=strlen("yyyy-mm-dd")) {
	player->printf("Date must be in yyyy-mm-dd format.\n");
	return true;
      }
      if (!isdigit(text[0]) ||
	  !isdigit(text[1]) ||
	  !isdigit(text[2]) ||
	  !isdigit(text[3]) ||
	  !isdigit(text[5]) ||
	  !isdigit(text[6]) ||
	  !isdigit(text[8]) ||
	  !isdigit(text[9]) ||
	  text[4] != '-' ||
	  text[7] != '-') {
	player->printf("Date must be in yyyy-mm-dd format.\n");
	return true;	
      }
      player->set("finger.dob", text.c_str());
      player->printf("OK.\n");
      return true;
    }

    bool ok = false;
    for (int i=0;i<ELEMENTS(setfinger);i++) {
	if (streq(setfinger[i].cmd, argv[0])) {
	    player->set(setfinger[i].id, text.c_str());
	    ok = true;
	}
    }
    player->printf(ok ? "OK.\n" : "THIS IS A BUG : PLEASE REPORT.\n");
    return true;
}

static void unreset(MudObject *who, MudObject *what) {
    if (what->get_flag(FL_GETFLIPS))
	what->set(KEY_STATE, 1);
    if (!what->owner) {
	set_owner(what, "@musicmud");
    }
    what->set("start", what->owner->id);
    what->set("initstate", state(what));

    if (MudObject *w=what->get_object(KEY_WIELD)) {
      if (w->get_flag(FL_DESTROYONRESET))
	who->printf("Warning: not set wield.start because it would be to a temporary object.");
      else
	what->set("wield.start", w->id);
    }
    if (MudObject *w=what->get_object(KEY_WORNBY)) {
      if (w->get_flag(FL_DESTROYONRESET))
	who->printf("Warning: not set wornby.start because it would be to a temporary object.");
      else
	what->set("wornby.start", w->id);
    }
    if (MudObject *w=what->get_object(KEY_SITON)) {
      if (w->get_flag(FL_DESTROYONRESET))
	who->printf("Warning: not set siton.start because it would be to a temporary object.");
      else
	what->set("siton.start", w->id);
    }
    what->unreset();
}

static bool verb_unreset(MudObject *player, int argc, const char **argv) {
    if (argc < 2) {
	player->printf("syntax : unreset objectname\n");
	return true;
    }
    
    MudObject *what = find_object(player, argv[1]);
    if (!what) {
	player->printf("Cannot find %s\n", argv[1]);
	return true;
    }

    if (what->get_flag(FL_DESTROYONRESET)) {
      player->printf("You can't unreset objects with DestroyOnReset flag.\n");
      return true;
    }

    unreset(player, what);
    
    player->printf("%s : reset state set.\n", what->id);
    
    return true;
}

static bool
verb_review (MudObject *who, int argc, const char **argv)
{
  MudObject *v=who;
  
  if (argc>1) {
    v = planet->get(argv[1]);
    if (!v) {
      who->printf("Look at whose travel messages?\n");
      return true;
    }
  }

  who->spec_printf("%s\n\n", title_for(ssprintf("Travel messages for %M", v), who).c_str());

  struct set_t {
    const char *str;
    setin_t s;
  } sets[] = 
    {
      { "setmin",   setmin, },
      { "setmout",  setmout, },
      { "setvin",   setvin, },
      { "setvout",  setvout, },
      { "setqin",   setqin, },
      { "setqout", setqout, },
      { "setsit",   setsit, },
      { "setstand",  setstand, },
      { "setsleep", setsleep, },
    };

  const char *name = v->get("name");

  bool yes = 0;

  for (int i=0;i<9;i++) {
    if (v->get(sets[i].str)) {
      who->printf("     %#8s : ^`^Z%s^'\n", sets[i].str, build_setin(v, get_message(v, sets[i].s), name, NULL, NULL).c_str());
      yes = 1;
    }
  }

  if (yes)
    who->printf("\n%s\n", footer_for(who).c_str());
  else {
    who->cancel_printf();
    who->printf("%#P %[has/have] no custom travel messages.\n", v);
  }

  return true;
}

static bool verb_flags(MudObject *who, int argc, const char **argv) {
    if (argc==1 || argv[1][0]=='|') {
	int i;
	vector<string> flags;
	size_t maxlen = 0, n = 0;
	for (i=0;i<FL_MAX;i++) {
	  if (strncmp(flag_names[i], "Spare", 5)==0)
	    continue;
	  if (argc>1 && !strcasestr(flag_names[i], argv[1]+1))
	    continue;
	  flags.insert(flags.begin(), flag_names[i]);
	  if (strlen(flag_names[i])>maxlen)
	    maxlen = strlen(flag_names[i]);
	}
	sort(flags.begin(), flags.end());
	for (vector<string>::iterator i = flags.begin();i!=flags.end();i++) {
	  who->printf("%-*s", maxlen+1, i->c_str());
	  n++;
	  if (n>=(columns(who)/(maxlen+1))-1) {
	    n=0;
	    who->printf("\n");
	  }
	}
        who->printf("\n");
	return true;
    }
    
    MudObject *what = find_object(who, argv[1]);
    if (!what) {
	who->printf("Cannot locate : %s\n", argv[1]);
	return true;
    }
    
    if (argc == 2) {
      who->spec_printf("^dFlags ^n");

      bool thing = 0;
      for (Flag i=FL_FIRST;i<FL_MAX;i++) {
	int a = what->get_rflag(i);
	int b = what->get_flag(i);

	if (a || b) {

	  if (a && b) who->printf("^d[^D%s^d]^n ", flag_names[i]);
	  if (!a && b) who->printf("+^d[^D%s^d]^n ", flag_names[i]);
	  if (a && !b) who->printf("(-%s) ", flag_names[i]);
	  thing = 1;
	}
      }

      if (thing) {
	who->printf("\n");
      } else {
	who->cancel_printf();
      }

      return true;
    }
    
    if (is_player(what) && !IS_ADMIRAL(who)) {
	who->printf("You can't set flags on players.\n");
	return true;
    }
    
    if (!cantouch_zone(who, what->get("zone")) && !who->ilc) {
	who->printf("You aren't authorised to modify that object.\n");
	return true;
    }
        
    int value = -1;
    if (argc == 4) {
	if (yes(argv[3])) value = 1;
	if (no(argv[3])) value = 0;
	if (value==-1) {
	    who->printf("Set it to what?\n");
	}
    }

    for (Flag l=FL_FIRST;l<FL_MAX;l++) {
	
	if (strcasecmp(argv[2], flag_names[l])==0) {
	    if (value != -1) {

	      if (streq(argv[0], "flags") || streq(argv[0], "tflags")) {
		what->set_flag(l, value);
	      }
	      if (streq(argv[0], "flags") || streq(argv[0], "rflags")) {
		what->set_rflag(l, value);
	      }
	    }

	    who->printf("%s::%s == %i (r:%i)\n", 
			what->id,
			flag_names[l],
			what->get_flag(l),
			what->get_rflag(l));
	    return true;
	}
    }
    who->printf("Unrecognised flag.\n");
    return true;
}

static bool verb_pflags(MudObject *who, int argc, const char **argv) {
    
  MudObject *what = 0;
  if (argc>1) {
    what = find_object(who, argv[1]);
    if (!what) {
      who->printf("Whose pflags?\n");
      return 1;
    }
  } else {
    what = who;
  }

  if (what != who && !who->get_priv(PFL_GOD)) {
    who->printf("I don't think so.\n");
    return true;
  }
    
  if (argv[1] && argv[2]) {
    PFlag p = find_priv(argv[2]);
    if (p == PFL_NONE) {
      who->printf("Can't find that pflag.\n");
      return true;
    }

    const char *now="";

    if (argv[3]) {
      if (streq(argv[3], "deny") || no(argv[3])) {
	if (!who->get_priv(PFL_GOD)) {
	  who->printf("I don't think so.\n");
	  return true;
	}
	if (!what->get_priv(p)) {
	  who->printf("%#P %[doesn't/don't] have %s.\n", who, priv_names[p]);
	  return true;
	}

	if (what->get_gpriv(p))
	  what->set_gpriv(p, 0);
	else
	  what->set_wpriv(p, 1);
	now = "now ";
      }
      if (streq(argv[3], "grant") || yes(argv[3])) {
	if (!who->get_priv(PFL_GOD)) {
	  who->printf("I don't think so.\n");
	  return true;
	}
	if (what->get_priv(p)) {
	  who->printf("%#P already %[has/have] %s.\n", what, priv_names[p]);
	  return true;
	}

	if (what->get_wpriv(p)) {
	  what->set_wpriv(p, 0);
	  if (!what->get_dpriv(p))
	    what->set_gpriv(p, 1);
	} else 
	  what->set_gpriv(p, 1);
	now = "now ";
      }

      if (streq(argv[3], "abey")) {
	what->set_apriv(p, 1);
	now = "now ";
      }
      if (streq(argv[3], "reclaim")) {
	what->set_apriv(p, 0);
	now = "now ";
      }

      if (!*now) {
	what->printf("Don't know how to %s - can deny and grant or abey and reclaim.\n", 
		    argv[3]);
      }
    }
    
    if (what->get_priv(p) && what->get_dpriv(p)) {
      who->printf("%#P %[is/are] %sentitled to and %[has/have] %s.\n", what, now, priv_names[p]);
      return true;
    }

    if (what->get_priv(p) && what->get_gpriv(p)) {
      who->printf("%#P %[has/have] %sbeen granted %s.\n", what, now, priv_names[p]);
      return true;
    }

    if (what->get_wpriv(p)) {
      who->printf("%#P %[has/have] %sbeen denied %s.\n", what, now, priv_names[p]);
      return true;
    }

    if (what->get_gpriv(p) && what->get_apriv(p)) {
      who->printf("%#P %[has/have] %sbeen granted %s but %[has/have] turned it off.\n", what, now,
		  priv_names[p]);
      return true;
    }

    if (what->get_dpriv(p) && what->get_apriv(p)) {
      who->printf("%#P %[is/are] %sentitled to %s but %[has/have] turned it off.\n", what, now, 
		  priv_names[p]);
      return true;
    }

    who->printf("%#P %s%[doesn't/don't] have %s.\n", what, now, priv_names[p]);
    return true;
  }

  who->spec_printf("%#P %[has/have] been granted: ", what);
  for (PFlag l=PFlag(2);l<PFL_MAX;l++)
    if (what->get_priv(l) && !what->get_dpriv(l))
      who->printf("%s ", priv_names[l]);
  if (who->cancel_printf())
    who->printf("\n");

  who->spec_printf("%#P %[is/are] entitled to: ", what);
  for (PFlag l=PFlag(2);l<PFL_MAX;l++)
    if (what->get_priv(l) && what->get_dpriv(l))
      who->printf("%s ", priv_names[l]);
  if (who->cancel_printf())
    who->printf("\n");

  who->spec_printf("%#P %[have/has] has been stripped of: ", what);
  for (PFlag l=PFlag(2);l<PFL_MAX;l++)
    if (what->get_wpriv(l))
      who->printf("%s ", priv_names[l]);
  if (who->cancel_printf())
    who->printf("\n");

  who->spec_printf("%#P %[have/has] placed in abeyance: ", what);
  for (PFlag l=PFlag(2);l<PFL_MAX;l++)
    if (what->get_dpriv(l) && !what->get_wpriv(l) && what->get_apriv(l))
      who->printf("%s ", priv_names[l]);
  if (who->cancel_printf())
    who->printf("\n");

  return true;
}


static bool verb_rows(Player *who, int argc, const char **argv)
{
  if (argc == 1) {
    who->printf("Syntax : rows <number>\n");
    return true;
  }
  if (atoi(argv[1])<10) {
    who->printf("Rows must be >= 10.\n");
    return true;
  }
  who->set("rows", atoi(argv[1]));

  if (who->p && who->p->col && !who->get_flag(FL_NONAWS)) {
    who->printf("Warning: NAWS is in effect, this overrides your set window size. Use 'NoNaws' to disable it'.\n");
    return true;
  }

  return true;
}

static bool verb_columns(Player *who, int argc, const char **argv)
{
  if (argc == 1) {
    who->printf("Syntax : columns <number>\n");
    return true;
  }
  if (atoi(argv[1])<10) {
    who->printf("Columns must be >= 10.\n");
    return true;
  }
  if (atoi(argv[1])>320) {
    who->printf("Columns must be <= 320.\n");
    return true;
  }
  who->set("columns", atoi(argv[1]));

  if (who->p && who->p->col && !who->get_flag(FL_NONAWS)) {
    who->printf("Warning: NAWS is in effect, this overrides your set window size. Use 'NoNaws' to disable it'.\n");
    return true;
  }
  
  who->printf("Done.\n");

  return true;
}


static bool verb_wimpy(MudObject *who, int argc, const char **argv)
{
  if (argc == 1) {
    who->printf("Syntax : wimpy <number>\n");
    return true;
  }
  who->set("wimpy", atoi(argv[1]));
  return true;
}

static void compose_desc(Player *who, const char *what) {
  if (streq(what, ".") || streq(what, "**")) {
    who->pop_state();
        
    MudObject *what = (MudObject *)planet->get(who->get("!desc.what"));
    if (!what) {
      who->printf("Can't find that object.\nOops. Hope that description wasn't very long :).\n");
      return;
    }
    string descbuffer = who->get("!desc.buffer");
    if (descbuffer.length()==0) {
	what->unset(who->get("!desc.prop"));
    } else {
      if (strncmp(who->get("!desc.prop"), "lua.", 4)==0)
      {
	string db = ",";
	db += who->id;
	db += ",1;";
	db += descbuffer;
	descbuffer = db;
      }
      descbuffer.erase((int)descbuffer.length()-1, 1);
      what->set(who->get("!desc.prop"), descbuffer.c_str());
      log(PFL_SEEINFO, LEV_INTERNAL, "fiddle", "set %s :: %s with desc", what->id, who->get("!desc.prop"));
    }
  }
  if (streq(what, "!") || streq(what, "~")) {
    who->printf("OK. abandoning desc\n");
    who->pop_state();
  }
  string descbuffer = who->get("!desc.buffer");
  descbuffer += what; 
  descbuffer += "\n";
  who->set("!desc.buffer", descbuffer.c_str());
}

static bool verb_namestyle(MudObject *w, int argc, const char **argv) {
  MudObject *what = w->owner;
  if (!cantouch_zone(w, what->get("zone"))) {
    w->printf("You don't have write privs here.\n");
    return true;
  }
  int wanted = DIRECT;
  if (argc>1) {
    string a = argv[1];
    if (argc>2) {
      a += argv[2];
    }
    const char *b = a.c_str();
    if (streq(b, "in")) wanted = IN;
    if (streq(b, "inthe")) wanted = IN_THE;
    if (streq(b, "on")) wanted = ON;
    if (streq(b, "onthe")) wanted = ON_THE;
    if (streq(b, "by")) wanted = BY;
    if (streq(b, "bythe")) wanted = BY_THE;
    if (streq(b, "at")) wanted = AT;
    if (streq(b, "atthe")) wanted = AT_THE;
    if (streq(b, "onboard")) wanted = ON_BOARD;
  }
  w->owner->set("namestyle", wanted);
  return true;
}

static bool verb_description(MudObject *w, int argc, const char **argv) {
  if (argc < 2) {
    w->printf("syntax: description me, here, or <what>\n");
    return true;
  }
  if (!is_player(w)) {
	  w->printf("Sorry, only real players can do this..\n");
	  return true;
  }
  Player *who = (Player *)w;
  MudObject *what = planet->get(argv[1]);
  if (streq(argv[1], "me")) what = who;
  if (streq(argv[1], "here")) what = who->owner;
  if (streq(argv[1], "HERE")) what = who->owner;
  
  if (!what) {
    who->printf("Cannot find object called : %s\n", argv[1]);
    return true;
  }
  if (what->get_object("$player")==w) {
    who->set("!desc.what", what->id);
    who->set("!desc.buffer", "");
    who->set("!desc.prop", "$desc");
    who->printf(". to finish, ~ to abort.\n"); 
    who->push_state( "make.desc");
    return true;
  }
  if (!w->get_priv(PFL_MAKE) && what != w) {
    who->printf("You can only set your own (or your quarters') description.\n");
    return true;
  }

  int allow_custom = 0;

  if (what != who) {
    if (!cantouch_zone(who, what->get("zone"))) {
      who->printf("You can't edit that zone.\n");
      return true;
    }
    allow_custom = who->get_priv(PFL_CODER);
  } else {
    allow_custom = who->get_priv(PFL_CODER);
  }

  if (what->get_flag(FL_WILDERNESS)) {
    who->printf("You really don't want to edit that.\n");
    return true;
  }
  
  const char *prop = "desc";
  if (argv[2]) {
    if (allow_custom)
      prop = argv[2];
    else {
      who->printf("You can only set descriptions with desc.\n");
      return true;
    }
  }
  
  who->set("!desc.what", what->id);
  who->set("!desc.buffer", "");
  who->set("!desc.prop", prop);
  who->printf(". to finish, ~ to abort.\n"); 
  who->push_state( "make.desc");
  
  return true;
}

static bool verb_alias(MudObject *who, int argc, const char **argv)
{
	Divert d(who, "alias");
        if(argc==1)
	{
		int count=0;
		Object::strit i = who->strs.begin();
		while(i != who->strs.end())
		{
			const char *key = i->first.c_str();
			if(!strncmp(key,"alias.",6))
			{
				if(!count)who->printf("^WYour current aliases^n:\n");
				who->printf("%-13s ^B:^n %s\n",
						(key)+6 , 
						escape_colour((string)who->get(key)).c_str());
				count++;
			}
			i++;
		}
		if(!count) who->printf("^WYou have no aliases^n\n");
	} else if(argc==2)
	{
		//who->printf("Attempting to remove %s from your list of aliases...\n",argv[1]);
		char key[1024];
		snprintf(key,1024,"alias.%s",argv[1]);
		if(!(who->get(key)==NULL))
		{
			who->unset(key);
			who->printf("^W%s^n is no longer in your alias list.\n",argv[1]);
		} else {
			who->printf("Can't find ^W%s^n in your alias list.\n",argv[1]);
		}
	} else
	{
		if(!strcmp(argv[1],"alias"))
		{
			who->printf("An alias for alias? Don't be silly.\n");
			return true;
		}
		if(!strcmp(argv[2],"at") || !strcmp(argv[2],"by"))
		{
			who->printf("You can't create aliases for 'at' or 'by' for recursive reasons.\n");
			return true;
		}
		//who->printf("Attempting to add %s to your list of aliases...\n",argv[1]);
		char key[1024];
		snprintf(key,1024,"alias.%s",argv[1]);

		char value[1024];
		int counter=strlen(argv[2]);
		strncpy(value,argv[2],1023);
		value[1023]='\0';
		
		if(argc>=3)
			for(int i=3;i<argc;i++)
			{
				char temp[1024];
				snprintf(temp, 1024," %s",argv[i]);
				counter+=strlen(temp);
				if(counter>1023) break;
				strncat(value,temp,1023-counter);
			}
		value[1023]='\0';
		who->printf("Adding ^W%s^n (%s^n) to your alias list.\n",argv[1],escape_colour(value).c_str());
		Verb *v = verbs->get(argv[1]);
		if (v)
			who->printf("^RWarning^n: this overrides the '%s' command'.\n", v->id);
		who->set(key,value);
	}
	
	return true;
}

#if 0
bool verb_pn(MudObject *who, int argc, const char **argv) {


  who->printf("Me  : %M.\n", who);
  who->printf("It  : %Y.\n", who->get_object("!it"));

  who->printf("Her : %M.\n", who->get_object("!her"));
  who->printf("Him : %M.\n", who->get_object("!him"));
  who->printf("Them: %M.\n", who->get_object("!them"));

  return true;
}
#endif


static bool verb_timezone(MudObject *who, int argc, const char **argv)
{
  const char *tz = who->get("timezone");
  if (!tz) tz = MUD_DEFTZ;
  string tzs = tz;
  tz = tzs.c_str();
  if (argc==1) {
    who->printf("Your timezone is currently %s.\n", tz);
    return 1;
  }

  if (argc==2) {
    who->set("timezone", argv[1]);
    who->printf("Your timezone is now %s (was %s).\n", argv[1], tz);
  }
  return true;
}

#define CREATE_VERB(what) \
static bool verb_##what(MudObject *who, int argc, const char **argv) { \
  if (argc==1) { who->printf("syntax: " #what " <message>\n"); \
  return true; } string txt = the_rest(argc, argv, 1); \
  if (streq(txt.c_str(), "\\")) who->unset(#what); else who->set(#what, txt.c_str()); \
  return true; }

CREATE_VERB(setmin)
  CREATE_VERB(setmout)
  CREATE_VERB(setqin)
  CREATE_VERB(setqout)
  CREATE_VERB(setvin)
  CREATE_VERB(setvout)
  
#include "verbmodule.h"
  
  void startup() {
  
#define SET(a) AUTO_VERB(set##a, THING, 0, PFL_SETIN)
#define THING 5
  SET(vin);
  SET(vout);
  SET(qin);
  SET(qout);
  SET(min);
  SET(mout);
#undef THING
  
#define verb_tflags verb_flags
#define verb_rflags verb_flags
  
  AUTO_VERB(timezone, 5, 0, PFL_NONE);
  
  AUTO_VERB(prompt, 4, 0, PFL_NONE);
  AUTO_VERB(unreset, 5, 0, PFL_MAKE);
  AUTO_VERB(flags, 2, 0, PFL_MAKE);
  AUTO_VERB(rflags, 2, 0, PFL_MAKE);
  AUTO_VERB(tflags, 2, 0, PFL_MAKE);
  
  AUTO_VERB(wimpy, 3, 0, PFL_NONE);
  
  AUTO_VERB(rows, 4, 0, PFL_NONE);
  AUTO_VERB(columns, 3, 0, PFL_NONE);
  ADD_ALIAS(cols, 4, columns);
  AUTO_VERB(pflags, 2, 0, PFL_NONE);
  AUTO_VERB(homeroom, 5, 0, PFL_GOTO);
  AUTO_VERB(nametransplant, 5, 0, PFL_NONE);
  AUTO_VERB(description, 4, 0, PFL_NONE);
  ADD_STATE("make.desc", "Desc : ", compose_desc, false);
  AUTO_VERB(alias,5,0,PFL_NONE);
  
  AUTO_VERB(namestyle, 2, 0, PFL_MAKE); 
  
  AUTO_VERB(review, 3, 0, PFL_SETIN);
  
#if 0
  AUTO_VERB(pn, 2, 0, PFL_NONE);
#endif
  
  for (int i=0;i<ELEMENTS(setfinger);i++) {
    ADD_VERB(setfinger[i].cmd, strlen(setfinger[i].cmd), verb_setfinger, 0, PFL_NONE);
  }

}