#include <stdio.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "config.h"
#include "structs.h"
#include "functions.h"
#include "utils.h"
#include "command.h"
#include "db.h"

/* EXTERNAL VARIABLES */
extern struct zone_data *zone_list;
extern struct descriptor_data *desc_list, *next_desc;
extern struct object_data *object_list, *obj_proto_list;
extern struct char_data *mob_proto_list, *mob_list;
extern struct regen_index_element *regen_index;
extern struct regen_data *timed_regen;
extern struct cook_data *cook_list;
extern struct room_data *tmp_room;
extern int which,top_of_rooms,top_of_z_table,top_of_regen;
extern int top_of_p_table,top_of_mob_protos,top_of_obj_protos;
extern int items_cooking;
extern char  buf[SMALL_BUFSIZE];
extern char  buf1[SMALL_BUFSIZE];
extern char  buf2[SMALL_BUFSIZE];

void  do_heal(struct char_data *ch, char *arg)
{
}

void	do_pset(struct char_data *ch, char *arg)
{
   struct descriptor_data *who, *next_who;
   int level,i,c;

	if((!get_arg(buf,arg,1)) || !get_arg(buf1,arg,2) || !get_arg(buf2,arg,3)) {
		for(i=c=0;*data_list[i].name != '\n';i++) {
			if (c<4) {
				sprintf(buf,"%12s",data_list[i].name);
				c++;
			} else {
				sprintf(buf,"%12s\n",data_list[i].name);
				c=0;
			}
			send_2_output(buf,ch->desc);
		}
     	send_2_output("\n\nUse: pset <player name> <attribute> <value>\n\r",ch->desc);
		return;
   }

	for(i=0;*data_list[i].name != '\n';i++) {
      if(!shrt_cmp(buf1,data_list[i].name))
         break;
   }
   if(i == MAX_DATA) {
      send_2_output("Invalid attribute to set.\n\r",ch->desc);
      return;
   }

   /* See if we have a valid player name */
   for(who=desc_list;who;who=next_who) {
      next_who=who->next_in_list;
      if(!shrt_cmp(buf,who->NAME)) {
			if(_numeric(&level,buf2)) {
				if(data_list[i].max > 0) {
					if(data_list[i].max >= level && data_list[i].min <= level) {
						who->character->data[data_list[i].number]=level;
						send_2_output("Done.\n\r",ch->desc);
						if(who->character != ch) {
							sprintf(buf,"set your %s to %d\n\r",data_list[i].name,level);
							send_2_char(ch,who->character,IGNR_INVIS,buf);
						}
					} else {
						sprintf(buf,"%s must be between %d and %d\n\r",data_list[i].name,data_list[i].min,data_list[i].max);
						send_2_output(buf,ch->desc);
						return;
					}
				}
			}
			update_char(who->character);
			return;
      }
   }
   send_2_output("They are not logged on!\n\r",ch->desc);
   return;
}

void do_clone(struct char_data *ch,char *arg,int mode)
{
	struct object_data *obj, *obj_next;
	int c,number = -1;

	if(!get_arg(buf,arg,-1)) {
		send_2_output("Usage: clone <number | name>\n\r",ch->desc);
		return;
	}

	if(mode != ALWAYS) {
		/* have to calculate fail attempts */
	}

	if(_numeric(&number,buf)) {
		obj = clone_object(number,NEW_OBJECT);
	} else {
		for(obj=obj_proto_list;obj;obj=obj_next) {
			obj_next=obj->next_in_list;
			if(obj_cmp(buf,obj)) {
				obj = clone_object(obj->IDNUM,NEW_OBJECT);
				break;
			}
		}
	}
	
	if(obj) {
		obj_2_char(obj,ch);
		sprintf(buf,"You successfully clone %s\n\r",obj->name);
		send_2_output(buf,ch->desc);
	} else {
		send_2_output("Could not clone that object.\n\r",ch->desc);
	}
}

void	do_tohand(struct char_data *ch, char *arg)
{
	struct object_data *obj, *obj_next;
	int 	 number, which;

	if(!get_arg(buf,arg,-1)) {
		send_2_output("Usage: tohand <object number | object name>\n\r",ch->desc);
		return;
	}

	/* Get which one we want */
	which = get_which(buf);

	if(_numeric(&number,buf)) {
		obj=get_proto_object(number);
	} else {
		for(obj=obj_proto_list;obj;obj=obj_next) {
			obj_next=obj->next_in_list;
			if(obj_cmp(buf,obj))
				break;
		}
	}

	/* Do we have an object? */
	if(obj) {
		/* Skip past the proto-type */
		obj=obj->next_of_type;

		for(;obj;obj=obj_next) {
			obj_next=obj->next_of_type;
			if(--which == 0) {
				if(obj->carried_by) {
					sprintf(buf,"You get %s from %s\n\r",obj->name,obj->carried_by->name);
					obj_from_char(obj);
				} else if (obj->contained_in) {
					sprintf(buf,"You get %s from inside %s\n\r",obj->name,obj->contained_in->name);
					obj_from_obj(obj);
				} else {
					sprintf(buf,"You get %s from room %d\n\r",obj->name,OBJECT_ROOM);
					obj_from_room(obj);
				}
				obj_2_char(obj,ch);
				send_2_output(buf,ch->desc);
				return;
			}
		}
	}

	/* If we get to here we didn't find an object
		or it wasn't available to this character! */
	send_2_output("Object not found or unattainable!\n\r",ch->desc);
}

void	do_reroll(struct char_data *ch, char *arg)
{
	struct descriptor_data *point, *next_point;

	if(!get_arg(buf,arg,1)) {
		send_2_output("reroll who?\n\r",ch->desc);
		return;
	}

	for(point=desc_list;point;point=next_point) {
		next_point=point->next_in_list;
		if(!shrt_cmp(buf,point->NAME)) {
			roll_char(point->character);
			sprintf(buf,"Done:\n\rSTR: %d  INT: %d  WIS: %d  DEX: %d  CON: %d\n\r",point->character->STR,point->character->INT,point->character->WIS,point->character->DEX,point->character->CON);
			send_2_output(buf,ch->desc);
			update_char(point->character);
			return;
		}
	}
	send_2_output("They are not logged on!\n\r",ch->desc);
}

/*******************************************************************
	Modified 26/12/99 by Matt.
	Fixed bug where zone got corrupted, and added goto 'player'
	feature.  Maybe will add goto 'mob' feature when I have decided
	on a quick way to search through all mobs in game...
*******************************************************************/
void	do_goto(struct char_data *ch, char *arg)
{
	struct char_data *tgt;
	int c,i;
	int x_y_z[5];

	if((get_arg(buf,arg,1)) && !_numeric(&x_y_z[0],buf)) {
		if(!(tgt=get_player(buf))) {
			send_2_output("They don't appear to be here...\n\r",ch->desc);
			return;
		} else if((tgt ==  ch) || (IN_ROOM(tgt) == IN_ROOM(ch))) {
			send_2_output("You are already there!\n\r",ch->desc);
			return;
		} else {
			char_from_room(ch,"Slowly fades from existance");
			char_2_room(ch,tgt->in_room,"Slowly appears before your eyes");
			return;
		}
	} else {
		for(c=1;(c<5) && get_arg(buf,arg,(c+1));c++) {
			if(!_numeric(&x_y_z[c],buf)) {
				send_2_output("I don't know how to get there\n\r",ch->desc);
				return;
			}
		}
	}

	switch(c) {
		case 1:
			x_y_z[3] = x_y_z[0];
			x_y_z[0] = GET_X(ch);
			x_y_z[1] = GET_Y(ch);
			x_y_z[2] = GET_Z(ch);
			break;
		case 2:
			if(x_y_z[0] > top_of_z_table || x_y_z[0] < 0) {
				send_2_output("That zone does not exist.\n\r",ch->desc);
				return;
			}
			x_y_z[3] = x_y_z[1];
			x_y_z[2] = ZONE_Z(x_y_z[0]);
			x_y_z[1] = ZONE_Y(x_y_z[0]);
			x_y_z[0] = ZONE_X(x_y_z[0]);
		case 4:
			break;
	  default:
			send_2_output("Goto where?\n\r",ch->desc);
			return;
	};
	if(x_y_z[3] > (ZONE_SIZE-1) || x_y_z[3] < 0) {
		send_2_output("That room number does not exist\n\r",ch->desc);
	} else {
		char_from_room(ch,"Slowly fades from existance");
		tmp_room = get_room(x_y_z[0],x_y_z[1],x_y_z[2],x_y_z[3]);
		if(!BTST(tmp_room->flags,WATER_ROOM) && ch->POSITION == POS_SWIMMING)
			ch->POSITION = POS_STANDING;
		char_2_room(ch,tmp_room,"Slowly appears before your eyes");
	}
	return;
}

void	do_stat(struct char_data *ch, char *arg)
{
	struct object_data *obj, *obj_next;
	struct char_data *pl, *pl_next, *mob, *mob_next;
	int number,zone,room,which;

	/* Find out wich command we are (pstat,ostat,rstat) */
	if(!get_arg(buf2,arg,1)) {
		game_stats(ch);
		return;
	} else if(!get_arg(buf,arg,-2)) {
		send_2_output("Usage: stat <m[p] | o[p] |r> <name | number>\n\r",ch->desc);
		return;
	}

	/* Get which one we want */
	which = get_which(buf);

	switch(*buf2) {
		case 'o':
			if(_numeric(&number,buf)) {
				obj=get_proto_object(number);
			} else {
				for(obj=obj_proto_list;obj;obj=obj_next) {
					obj_next=obj->next_in_list;
					if(obj_cmp(buf,obj))
						break;
				}
			}
			/* Do we have an object? */
			if(!obj)
				break;

 			/* Skip past the proto-type */
			if (buf2[1] != 'p')
				 obj=obj->next_of_type;

			for(;obj;obj=obj_next) {
				obj_next=obj->next_of_type;
				if(--which == 0) {
					show_object(ch, obj);
					return;
				}
			}
			break;
		case 'r':
			zone = ch->in_room->ZONE;
         if(!(((get_arg(buf,arg,3)) && (_numeric(&room,buf) ? 1 : 0)) ? 
              ((get_arg(buf,arg,2)) && (_numeric(&zone,buf) ? 1 : 0)) :
              ((get_arg(buf,arg,2)) && (_numeric(&room,buf) ? 1 : 0)))) {
				send_2_output("Non numerical zone/room number\n\r",ch->desc);
			} else if(ZONE_ROOM(zone,room)) {
            show_room(ch,ZONE_ROOM(zone,room));
         } else {
				sprintf(buf,"zone %d room %d: Does not exist\n\r",zone,room);
				send_2_output(buf,ch->desc);
			}
			return;
			break;
		case 'm':
         if(_numeric(&number,buf)) {
            mob=get_proto_mob(number);
         } else {
            for(mob=mob_proto_list;mob;mob=mob_next) {
               mob_next=mob->next_in_list;
               if(mob_cmp(buf,mob)) 
						break;
				}
			}
			/* Check if we have a valid target */
			if(!mob)
				break;
			
 			/* Skip past the proto-type */
			if(buf2[1] != 'p')
				 mob=mob->next_of_type;

			for(;mob;mob=mob_next) {
				mob_next=mob->next_of_type;
				if(--which == 0) {
					show_mob(ch, mob);
					return;
            }
         }
         break;
	}
	send_2_output("No match found.\n\r",ch->desc);
	return;
}

void  show_object(struct char_data *ch, struct object_data *obj)
{
	struct affect_data *aff, *aff_next;
   int c;

   sprintf(buf,"  Number: %d\n\r    name: %s\n\rLocation: ",obj->IDNUM,obj->name);
   send_2_output(buf,ch->desc);

	if(obj->contained_in) {
		sprintf(buf,"Inside %s\n\r    Type: ",obj->contained_in->name);
	} else if(obj->carried_by) {
		sprintf(buf,"Carried by %s\n\r    Type: ",obj->carried_by->name);
	} else if(OBJECT_ROOM) {
		sprintf(buf,"%s [%d,%d,%d][%d][%d]\n\r    Type: ",
			obj->in_room->name,
			obj->in_room->X,obj->in_room->Y,obj->in_room->Z,
			obj->in_room->IDNUM,obj->in_room->ZONE);
	} else {
		sprintf(buf,"Not Available\n\r    Type: ");
	}
   send_2_output(buf,ch->desc);

   if(obj->TYPE) {
		for(c=0;obj_type_flag[c].setbit != 0;c++) {
      	if(BTST(obj->TYPE,obj_type_flag[c].setbit)) {
         	sprintf(buf,"%s ",obj_type_flag[c].name);
         	send_2_output(buf,ch->desc);
      	}
   	}
	}

	sprintf(buf,"\n\r   Regen: %s",obj->REGEN ? "TRUE" : "FALSE");
	send_2_output(buf,ch->desc);

	if(obj->CLASS) {
		send_2_output("\n\r   Class: ",ch->desc);
		class_2_string(ch, obj->CLASS);
	}

   if(obj->SEX) {
      send_2_output("\n\r     Sex: ",ch->desc);
		sex_2_string(ch, obj->SEX);
   }

   if(obj->ALIGN) {
      send_2_output("\n\r   Align: ",ch->desc);
		align_2_string(ch, obj->ALIGN);
   }

	if(obj->WORN) {
		send_2_output("\n\r    Worn: ",ch->desc);
		for(c=0;obj_worn_flag[c].setbit != 0;c++) {
			if(BTST(obj->WORN,obj_worn_flag[c].setbit)) {
				sprintf(buf,"%s ",obj_worn_flag[c].name);
				send_2_output(buf,ch->desc);
			}
		}
	}

	sprintf(buf,"\n\r     Die: %d D %d + %d\n\r  b_data: ",
		obj->OBJ_DIE,obj->OBJ_SIZE,obj->OBJ_BONUS);
	send_2_output(buf,ch->desc);

	for(c=6;c<14;c++) {
		sprintf(buf,"%d ",obj->data[c]);
		send_2_output(buf,ch->desc);
	}

	sprintf(buf,"\n\r   Value: %d coins\n\r  Weight: %d\n\r",
		obj->OBJ_VALUE,obj->OBJ_WEIGHT);
	send_2_output(buf,ch->desc);

	sprintf(buf," Special: %d\n\r",obj->OBJ_SPECIAL);
	send_2_output(buf,ch->desc);

	if(obj->affect) {
		send_2_output(" Adjusts: ",ch->desc);
		for(aff=obj->affect;aff;aff=aff_next) {
			aff_next=aff->next;
			for(c=0;data_list[c].number != aff->affect;c++);
			sprintf(buf,"%s %d  ",data_list[c].name,aff->value,aff->affect);
			send_2_output(buf,ch->desc);
		}
		send_2_output("\n\r",ch->desc);
	}
	return;
}

void  show_room(struct char_data *ch, struct room_data *room)
{
   struct affect_data *aff, *aff_next;
   int c;

   sprintf(buf,"   name: %s\n\r",room->name);
   send_2_output(buf,ch->desc);

	sprintf(buf,"Min lvl: %d\n\rMax lvl: %d\n\rSpecial: %d\n\r  Flags: ",
				room->MIN_LEVEL,room->MAX_LEVEL,room->OBJ_SPECIAL);
	send_2_output(buf,ch->desc);

	if(room->flags) {
		for(c=0;room_flag[c].setbit != 0;c++) {
			if(BTST(room->flags,room_flag[c].setbit)) {
				sprintf(buf,"%s ",room_flag[c].name);
				send_2_output(buf,ch->desc);
			}
		}
	}

   if(room->CLASS) {
      send_2_output("\n\r  Class: ",ch->desc);
		class_2_string(ch, room->CLASS);
   }

   if(room->SEX) {
      send_2_output("\n\r    Sex: ",ch->desc);
		sex_2_string(ch, room->SEX);
   }

   if(room->ALIGN) {
      send_2_output("\n\r  Align: ",ch->desc);
		align_2_string(ch, room->ALIGN);
   }
	send_2_output("\n\r",ch->desc);
   return;
}

void	do_pardon(struct char_data *ch, char *arg)
{
	struct char_data *player;

	if(!get_target(buf,arg,1)) {
		send_2_output("You are excused...\n\r",ch->desc);
	} else if(!(player=get_player(buf))) {
		send_2_output("No one exists by that name.\n\r",ch->desc);
	} else {
		BCLR(player->SPECIALS,PKILLER);
		if(player == ch)
			send_2_output("You pardon yourself.\n\r",ch->desc);
		else {
			sprintf(buf,"You pardon %s\n\r",player->name);
			send_2_output(buf,ch->desc);
			send_2_char(ch,player,INVIS_CHK,"has pardoned you.");
		}
	}
}

void	game_stats(struct char_data *ch)
{
	extern struct timeval boot_time,now,gametime,timespent;
	extern int min_login,sock_connected,sock_playing,max_users;
	extern int sock_logins;
	extern long seed;
	int	c;

	send_2_output("Current game stats:\n\r",ch->desc);

	sprintf(buf,"started: %s",asctime(localtime((time_t *)&boot_time)));
	send_2_output(buf,ch->desc);
	sprintf(buf,"Running: %d Days %d Hours %d Minutes\n\r",
		(gametime.tv_sec/((60*60)*24)),(gametime.tv_sec/(60*60)),(gametime.tv_sec/60));
	send_2_output(buf,ch->desc);
	sprintf(buf,"    USERS: %4d connected   %4d playing   %3d connections since bootup\n\r",sock_connected,sock_playing,sock_logins);
	send_2_output(buf,ch->desc);
	sprintf(buf,"MAX USERS: %4d",max_users);
	if(min_login == 1)
		sprintf(buf1,"%s (No new characters allowed)\n\r",buf);
	else if(min_login)
		sprintf(buf1,"%s (Allowing characters at level %d and above)\n\r",buf,min_login);
	else
		sprintf(buf1,"%s (Allowing new characters and above)\n\r",buf);
	send_2_output(buf1,ch->desc);
	sprintf(buf," %4d ZONES  %4d ROOMS  %4d MOBILES  %4d OBJECTS  %4d PLAYERS\n\r",
		(top_of_z_table+1),top_of_rooms,top_of_mob_protos,top_of_obj_protos,(top_of_p_table +1));
	send_2_output(buf,ch->desc);
	return;
}

void	do_restrict(struct char_data *ch, char *arg)
{
	extern int min_login;
	int	size;

	if(!get_arg(buf,arg,1)) {
		send_2_output("Usage: restrict <level>\n\r",ch->desc);
	} else if(!_numeric(&size,buf)) {
		send_2_output("The arguement must be numeric.\n\r",ch->desc);
	} else if(size > IMP) {
		send_2_output("You can't restrict above Implementor.\n\r",ch->desc);
	} else if(size < 0) {
		send_2_output("You can't restrict below 0\n\r",ch->desc);
	} else {
		min_login = size;
		if(size == 1) {
			send_2_output("OK. No new characters allowed.\n\r",ch->desc);
		} else if(size) {
			sprintf(buf,"OK. Restricting logins to level %d and above.\n\r",size);
			send_2_output(buf,ch->desc);
		} else {
			send_2_output("OK. No restrictions.\n\r",ch->desc);
		}
	}
	return;
}

void	show_mob(struct char_data *ch, struct char_data *mob)
{
	struct say_data *say, *say_next;
	int c;

	sprintf(buf,"   Number: %d\n\r     Name: %s\tAge: %d\t\tLevel: %d\n\r",
			mob->IDNUM,mob->name,mob->AGE,mob->LEVEL);
	send_2_output(buf,ch->desc);
	sprintf(buf,"    Regen: %s\n\r", mob->REGEN ? "TRUE" : "FALSE");
	send_2_output(buf,ch->desc);
	sprintf(buf,"Long Name: %s\n\r     Desc: %s\n\r",mob->l_name,mob->description);
	send_2_output(buf,ch->desc);
	sprintf(buf,"    Title: %s\n\r Position: %s\n\r",
			mob->title,show_pos[mob->POSITION].shrt);
	send_2_output(buf,ch->desc);

	if(mob->says) {
		for(c=0,say=mob->says;say;say=say_next,c++) {
			say_next=say->next;
			sprintf(buf," Emote %2d: %s\n\r",c,say->sentence);
			send_2_output(buf,ch->desc);
		}
	}
	send_2_output("  Descrim: ",ch->desc);
	if(mob->ANTI_SEX)
		sex_2_string(ch, mob->ANTI_SEX);
	if(mob->ANTI_CLASS)
		class_2_string(ch, mob->ANTI_CLASS);
	if(mob->ANTI_ALIGN)
		align_2_string(ch, mob->ANTI_ALIGN);
	send_2_output("\n\r    Flags: ",ch->desc);
	for(c=0;*mob_flag[c].name != '\n';c++) {
		if(BTST(NPC_FLAGS(mob),mob_flag[c].setbit)) {
			sprintf(buf,"%s ",mob_flag[c].name);
			send_2_output(buf,ch->desc);
		}
	}

	sprintf(buf,"\n\rSTR %d  WIS %d  INT %d  CON %d  DEX %d\n\r",
			mob->STR,mob->WIS,mob->INT,mob->CON,mob->DEX);
	send_2_output(buf,ch->desc);
 	sprintf(buf,"Hit %d(%d)  Mana %d(%d)  Move %d(%d)\n\r",
			mob->HIT,mob->MAX_HIT,mob->MANA,mob->MAX_MANA,mob->MOVE,mob->MAX_MOVE);
	send_2_output(buf,ch->desc);
	sprintf(buf,"WEIGHT %d (lbs)  HEIGHT %d (cm)  GOLD %d (coins)  EXP %d\n\r",
		mob->WEIGHT,mob->HEIGHT,mob->GOLD,mob->EXP);
	send_2_output(buf,ch->desc);
	sprintf(buf,"AC %d/10  THAC0 %d\n\r",mob->ARMOR,mob->THAC0);
	send_2_output(buf,ch->desc);
	return;
}

void	align_2_string(struct char_data *ch, char align)
{
	int c;

   for(c=0;*anti_align_flag[c].name != '\n';c++) {
      if(BTST(align,anti_align_flag[c].setbit)) {
         sprintf(buf,"%s ",anti_align_flag[c].name);
         send_2_output(buf,ch->desc);
      }
   }
}

void	sex_2_string(struct char_data *ch, char sex)
{
	int c;

   for(c=0;*anti_sex_flag[c].name != '\n';c++) {
      if(BTST(sex,anti_sex_flag[c].setbit)) {
         sprintf(buf,"%s ",anti_sex_flag[c].name);
         send_2_output(buf,ch->desc);
      }
   }
}

void	class_2_string(struct char_data *ch, char class)
{
	int c;

   for(c=0;*anti_class_flag[c].name != '\n';c++) {
      if(BTST(class,anti_class_flag[c].setbit)) {
         sprintf(buf,"%s ",anti_class_flag[c].name);
         send_2_output(buf,ch->desc);
      }
   }
}

void	do_list(struct char_data *ch, char *arg)
{
	extern struct player_index_element *player_table;
	extern struct object_index_element *obj_proto_index;
	extern struct npc_index_element *mob_proto_index;
	struct object_data *obj, *obj_next;
	struct char_data *mob, *mob_next;
	struct cook_data *ck_item;
	int   zone=0;
	int	size=0,c,count,max,in_world;

	/* Get the basic arguements */
	get_arg(buf,arg,1);
	
	if(!get_arg(buf1,arg,2) || _numeric(&size,buf1)) {
		switch(*buf) {
			case 'a':
				if(top_of_regen == 0) {
					send_2_output("No auto regenerative objects in the world.\n\r",ch->desc);
					return;
				}

				if(size >= top_of_regen) {
					send_2_output("Not that many auto regenerative objects.\n\r",ch->desc);
					return;
				}
				send_2_output(" TYPE     NUMBER   INTERVAL   COUNTER RUNNING   NAME\n\r",ch->desc);
      	   for(c=size;c<(size+20) && c<top_of_regen;c++) {
					switch(regen_index[c].item->type) {
					case IS_OBJECT:
						sprintf(buf,"Object:   [%5d]   [%5d]   [%5d]  %5s    %s\n\r",
							(regen_index[c].item->proto.ob ? regen_index[c].item->proto.ob->IDNUM : -1),
							regen_index[c].item->time,
							regen_index[c].item->counter,
							regen_index[c].item->data.ob ? "FALSE" : "TRUE",
							(regen_index[c].item->proto.ob ? regen_index[c].item->proto.ob->name : "<No Prototype>"));
						break;
					case IS_ZONE:
						sprintf(buf,"  Zone:   [%5d]   [%5d]   [%5d]  %5s    %s\n\r",
							regen_index[c].item->proto.zo,
							regen_index[c].item->time,
							regen_index[c].item->counter,
							regen_index[c].item->data.zo ? "FALSE" : "TRUE",
							(regen_index[c].item->proto.zo ? "N/A" : "<No Prototype>"));
						break;
					case IS_ROOM:
						sprintf(buf,"  Room:   [%5d]   [%5d]   [%5d]  %5s    %s\n\r",
							(regen_index[c].item->proto.ro ? regen_index[c].item->proto.ro->IDNUM : -1),
							regen_index[c].item->time,
							regen_index[c].item->counter,
							regen_index[c].item->data.ro ? "FALSE" : "TRUE",
							(regen_index[c].item->proto.ro ? "N/A" : "<No Prototype>"));
						break;
					case IS_CHAR:
						sprintf(buf,"   Mob:   [%5d]   [%5d]   [%5d]  %5s    %s\n\r",
							(regen_index[c].item->proto.ch ? regen_index[c].item->proto.ch->IDNUM : -1),
							regen_index[c].item->time,
							regen_index[c].item->counter,
							regen_index[c].item->data.ch ? "FALSE" : "TRUE",
							(regen_index[c].item->proto.ch ? regen_index[c].item->proto.ch->name : "<No Prototype>"));
						break;
					deafult:
					}
					send_2_output(buf,ch->desc);
      	   }
				return;
			case 'o':
				if(top_of_obj_protos == -1) {
					send_2_output("No objects in the world.\n\r",ch->desc);
					return;
				}
			
				for(c=0;(c<top_of_obj_protos) && obj_proto_index[c].object->IDNUM < size;c++);
				if(c == top_of_obj_protos) {
					send_2_output("No objects found.\n\r",ch->desc);
					return;
				}

				send_2_output(" NUMBER\t MAXIMUM  CURRENT  IN_GAME   NAME\n\r",ch->desc);
				for(c=c,size=c+20;c<size && c<top_of_obj_protos;c++) {
					max = obj_proto_index[c].object->OBJ_MAX;
					in_world = obj_proto_index[c].object->OBJ_COUNT;
					for(obj=obj_proto_index[c].object->next_of_type,count=0;obj;obj=obj_next) {
						obj_next=obj->next_of_type;
						count++;
					}
      	      sprintf(buf,"[%5d]   [%4d]   [%4d]   [%4d]   %s\n\r",
					obj_proto_index[c].object->IDNUM, max,
               in_world, count, obj_proto_index[c].object->name);
					send_2_output(buf,ch->desc);
				}
				return;
			case 'r':
				if(get_arg(buf2,arg,3)) {
					zone = size;
					if(!_numeric(&size,buf2)) {
						send_2_output("Non numerical zone/room number\n\r",ch->desc);
						return;
					}
				} else {
					zone = 0;
				}
				send_2_output(" ZONE     ROOM    NAME\n\r",ch->desc);
				for(count=0;(count < 20) && (zone <= top_of_z_table);) {
					if(ZONE_ROOM(zone,size)) {
      	      	sprintf(buf,"[%3d]    [%3d]    %s\n\r",zone,size,ZONE_ROOM(zone,size)->name);
      	      	send_2_output(buf,ch->desc);
						count++;
					}
					if((++size) > (ZONE_SIZE-1)) {
						zone++;
						size=0;
					}
				}
				if(!count)
					send_2_output("No match found\n\r",ch->desc);
				return;
			case 'm':
				if(top_of_mob_protos == -1) {
					send_2_output("No mobiles in the world.\n\r",ch->desc);
					return;
				}

				for(c=0;(c<top_of_mob_protos) && mob_proto_index[c].mob->IDNUM < size;c++);
				if(c == top_of_mob_protos) {
					send_2_output("No mobiles found.\n\r",ch->desc);
					return;
				}
				send_2_output("NUMBER    IN_GAME    NAME\n\r",ch->desc);
      	   for(c=c,size=c+20;c<size && c<top_of_mob_protos;c++) {
					for(mob=mob_proto_index[c].mob->next_of_type,count=0;mob;mob=mob_next) {
							mob_next=mob->next_of_type;
							count++;
					}
      	      sprintf(buf,"[%4d]      [%3d]    %s\n\r",
								mob_proto_index[c].mob->IDNUM,count,mob_proto_index[c].mob->l_name);
					send_2_output(buf,ch->desc);
      	   }
				return;
			case 'p':
				send_2_output("File ID\t\tLevel\t\tName\n\r",ch->desc);
      	   for(c=size,size+=20;c<size && c<=top_of_p_table;c++) {
      	      sprintf(buf,"[%4d]\t\t%d\t\t%s\n\r",c,player_table[c].level,player_table[c].name);
      	      send_2_output(buf,ch->desc);
      	   }
				return;
			case 't':
				if(items_cooking == 0) {
					send_2_output("No items on timed removal.\n\r",ch->desc);
					return;
				}

				if(size >= items_cooking) {
					send_2_output("Not that many items on timed removal.\n\r",ch->desc);
					return;
				}
				/* Move to the desired position */
				ck_item = cook_list;
				count=0;
				for(c=0;c<size;c++) {
					count += ck_item->counter;
					ck_item = ck_item->next;
				}

				send_2_output(" TYPE     NUMBER   TIME-LEFT   NAME\n\r",ch->desc);
      	   for(c=size;c<(size+20) && c<items_cooking;c++) {
					count += ck_item->counter;
					switch(ck_item->type) {
					case IS_OBJECT:
						sprintf(buf,"Object:   [%5d]   [%5d]    %s\n\r",
							ck_item->data.ob->IDNUM,
							count,
							ck_item->data.ob->name);
						break;
					case IS_CHAR:
					case IS_ROOM:
					case IS_ZONE:
					}
					ck_item = ck_item->next;
					send_2_output(buf,ch->desc);
				}
				return;
			case 'z':
				if(top_of_z_table == -1) {
					send_2_output("No zones in the universe.\n\r",ch->desc);
					return;
				}
				send_2_output(" ZONE    RESET    COUNT    ROOMS    CO-ORDINATES\n",ch->desc);
				for(c=size,size+=20;c<size && c<=top_of_z_table;c++) {
					sprintf(buf,"[%3d]    [%3d]    [%3d]    [%3d]    [%d,%d,%d]\n",c,zone_list[c].reset,zone_list[c].countdown,
      	             zone_list[c].num_rooms,ZONE_X(c),ZONE_Y(c),ZONE_Z(c));
					send_2_output(buf,ch->desc);
				}
				return;
		}
	}
	send_2_output("Usage: list <a|m|o|p|r|t|z> [<number>]\n\r",ch->desc);
}

void do_private(struct char_data *ch, char *arg)
{
	extern int axis_limit;
	extern struct char_data *channel[];
	int num;

	if((!get_arg(buf,arg,1)) && ch->CON_STATE != CON_PLYNG) {
		send_2_room(ch,IGNR_INVIS,"leaves private mode.");
		change_status(ch,CON_PLYNG);
		send_2_output("You rejoin your surroundings.\n",ch->desc);
		send_2_room(ch,IGNR_INVIS,"stops being antisocial.");
		return;
	} else if((_numeric(&num,buf)) && num >= 0 && num <= 100) {
		if(ch->LEVEL < GOD && channel[num] != 0) {
			/* Search for a free channel */
			for(num=0;num<=100,channel[num] != 0;num++);

			/* Did we find one? */
			if(channel[num] != 0) {
				send_2_output("All channels are busy right now...\n\rPlease try again later.\n\r",ch->desc);
				return;
			} else {
				sprintf(buf,"That channel was busy...\n\rYou have been allocated channel %d\n\r",num);
			}
		} else {
			sprintf(buf,"You are now on private channel %d.\n\r",num);
		}
		send_2_output(buf,ch->desc);
		if(ch->CON_STATE != CON_PLYNG)
			send_2_room(ch,IGNR_INVIS,"has switched to a different channel.");
		else
			send_2_room(ch,IGNR_INVIS,"has just joined a private channel.");
		change_status(ch,num+CON_PRIVATE);
		return;
	}
	send_2_output("Use: private <channel #0-100>\n\r",ch->desc);
}
//// CRTH
void	do_send(struct char_data *ch,char *arg)
{
	struct	char_data *who, *who_2;
	int x_y_z[5];
	int	c;

	if(!get_arg(buf,arg,1))
	{
		sprintf(buf1,"Send who, where ???\n\r");
		send_2_output(buf1,ch->desc);
	}
	else
	{
		if(!(who=get_xuser(ch,buf)))
		{
			sprintf(buf2,"I can't find who you wish to send...\n\r");
			send_2_output(buf2,ch->desc);
		}
		else
		{
			get_arg(buf1,arg,2);
			if(!(who_2=get_xuser(ch,buf1)))
			{
					for(c=0;(c<5) && get_arg(buf,arg,(c+2));c++) 
					{
						if(!_numeric(&x_y_z[c],buf)) 
						{
							send_2_output("I don't know how to get there\n\r",ch->desc);
							return;
						}
					}	
				
			}
			else
			{
				if(!shrt_cmp(buf1,ch->name))
					c = 6;
				else
					c = 5;	
			}

			switch(c) 
			{
				case 1:
					x_y_z[3] = x_y_z[0];
					x_y_z[0] = GET_X(who);
					x_y_z[1] = GET_Y(who);
					x_y_z[2] = GET_Z(who);
					break;
				case 4:
					x_y_z[3] = x_y_z[3];
					x_y_z[1] = ZONE_Y(x_y_z[1]);
					x_y_z[2] = ZONE_Z(x_y_z[2]);
					x_y_z[0] = ZONE_X(x_y_z[0]);
					break;
				case 6:
					x_y_z[3] = ROOM_NUM(ch);
					x_y_z[0] = GET_X(ch);
					x_y_z[1] = GET_Y(ch);
					x_y_z[2] = GET_Z(ch);
					break;
				case 5:
printf("sendig %s to %s\n",who->name,who_2->name);
					x_y_z[3] = ROOM_NUM(who_2);
					x_y_z[0] = GET_X(who_2);
					x_y_z[1] = GET_Y(who_2);
					x_y_z[2] = GET_Z(who_2);
					break;
			  default:
					send_2_output("Send them where?\n\r",ch->desc);
printf("c = %d\n",c);
					return;
			}
printf("c = %d\n",c);
			if(x_y_z[3] > (ZONE_SIZE-1) || x_y_z[3] < 0) 
				send_2_output("That room number does not exist\n\r",ch->desc);
			else 
			{
				char_from_room(who,"Slowly fades from existance");
				tmp_room = get_room(x_y_z[0],x_y_z[1],x_y_z[2],x_y_z[3]);
				if(!BTST(tmp_room->flags,WATER_ROOM) && who->POSITION == POS_SWIMMING
){
					who->POSITION = POS_STANDING;}
				char_2_room(who,tmp_room,"Slowly appears before your eyes");

				sprintf(buf,"You have successfully sent %s to the room..\n\r",who->name);
				send_2_output(buf,ch->desc);
			}
		
		}
	}
}

