bast/
bast/area/
bast/backup/
bast/clans/
bast/doc/MSP/
bast/doc/OLC11/
bast/doc/OLC11/doc/
bast/doc/OLC11/options/
bast/log/
bast/mobprogs/
bast/player/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David   *
 *  Love, Guilherme 'Willie' Arnold, and Mitchell Tse.                     *
 *                                                                         *
 *  EnvyMud 2.0 improvements copyright (C) 1995 by Michael Quan and        *
 *  Mitchell Tse.                                                          *
 *                                                                         *
 *  EnvyMud 2.2 improvements copyright (C) 1996, 1997 by Michael Quan.     *
 *                                                                         *
 *  In order to use any part of this Envy Diku Mud, you must comply with   *
 *  the original Diku license in 'license.doc', the Merc license in        *
 *  'license.txt', as well as the Envy license in 'license.nvy'.           *
 *  In particular, you may not remove either of these copyright notices.   *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 *                                                                         *
 *  This code was freely distributed with the The Isles 1.1 source code,   *
 *  and has been used here for OLC - OLC would not be what it is without   *
 *  all the previous coders who released their source code.                *
 ***************************************************************************/

#if defined( macintosh )
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "olc.h"



/*
 * Local functions.
 */
AREA_DATA *get_area_data args( ( int vnum ) );

AREA_DATA *get_area_data( int vnum )
{
    AREA_DATA *pArea;

    for ( pArea = area_first; pArea; pArea = pArea->next )
	if ( pArea->vnum == vnum )
	    return pArea;

    return 0;
}

void display_resets( CHAR_DATA * ch )
{
    ROOM_INDEX_DATA *pRoom;
    MOB_INDEX_DATA  *pMob = NULL;
    RESET_DATA      *pReset;
    char             final	[MAX_STRING_LENGTH];
    char             buf	[MAX_STRING_LENGTH];
    int              iReset = 0;

    if ( !( pRoom = (ROOM_INDEX_DATA *) ch->desc->olc_editing ) )
	pRoom = ch->in_room;

    final[0] = '\0';

    send_to_char( "----------------------------------------------------------------------------\n\r", ch );
    for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
    {
	OBJ_INDEX_DATA  *pObj;
	MOB_INDEX_DATA  *pMobIndex;
	OBJ_INDEX_DATA  *pObjIndex;
	OBJ_INDEX_DATA  *pObjToIndex;
	ROOM_INDEX_DATA *pRoomIndex;

	final[0] = '\0';
	sprintf( final, "%2d: ", ++iReset );

	switch ( pReset->command )
	{
	    default:
		sprintf( buf, "Bad reset command: %c.", pReset->command );
		strcat( final, buf );
		break;

	    case 'M':
		if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Load mobile - bad mob %d.\n\r", pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
		{
		    sprintf( buf, "Load mobile - bad room %d.\n\r", pReset->arg3 );
		    strcat( final, buf );
		    continue;
		}

		pMob = pMobIndex;
		sprintf( buf, "M 0 %5d %2d %5d  * %s -> %s\n\r",
			pReset->arg1, pReset->arg2, pReset->arg3,
			pMob->short_descr, pRoomIndex->name );
		strcat( final, buf );

		/* check for pet shop */
		{
		    ROOM_INDEX_DATA *pRoomIndexPrev;

		    pRoomIndexPrev = get_room_index( pRoomIndex->vnum - 1 );
		    if ( pRoomIndexPrev
			&& IS_SET( pRoomIndexPrev->orig_room_flags, ROOM_PET_SHOP ) )
			final[14] = 'P';
		}

		break;

	    case 'O':
		if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Load object - bad object %d.\n\r",
			    pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		pObj = pObjIndex;

		if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
		{
		    sprintf( buf, "Load object - bad room %d.\n\r", pReset->arg3 );
		    strcat( final, buf );
		    continue;
		}

		sprintf( buf, "O 0 %5d  0 %5d  * %s -> %s\n",
			pReset->arg1,
			pReset->arg3,
			capitalize( pObj->short_descr ),
			pRoomIndex->name );
		strcat( final, buf );

		break;

	    case 'P':
		if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Put object - bad object %d.\n\r",
			    pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		pObj = pObjIndex;

		if ( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) )
		{
		    sprintf( buf, "Put object - bad to object %d.\n\r",
			    pReset->arg3 );
		    strcat( final, buf );
		    continue;
		}

		sprintf( buf,"P 0 %5d  0 %5d  * %s inside %s\n",
			pReset->arg1,
			pReset->arg3,
			capitalize( get_obj_index( pReset->arg1 )->short_descr ),
			pObjToIndex->short_descr );
		strcat( final, buf );

		break;

	    case 'G':
		if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Give object - bad object %d.\n\r",
			    pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		pObj = pObjIndex;

		if ( !pMob )
		{
		    sprintf( buf, "Give object - no previous mobile.\n\r" );
		    strcat( final, buf );
		    break;
		}

		    sprintf( buf, "G 0 %5d  0        *   %s\n",
			    pReset->arg1,
			    capitalize( pObjIndex->short_descr ) );
		strcat( final, buf );

		break;

	    case 'E':
		if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Equip object - bad object %d.\n\r",
			    pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		pObj = pObjIndex;

		if ( !pMob )
		{
		    sprintf( buf, "Equip object - no previous mobile.\n\r" );
		    strcat( final, buf );
		    break;
		}

		    sprintf( buf, "E 0 %5d  0 %5d  *   %s %s\n",
			    pReset->arg1,
			    pReset->arg3,
		    capitalize( get_obj_index( pReset->arg1 )->short_descr ),
		    flag_string( wear_loc_strings, pReset->arg3 ) );
		strcat( final, buf );

		break;

	    case 'R':
		if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
		{
		    sprintf( buf, "Randomize exits - bad room %d.\n\r",
			    pReset->arg1 );
		    strcat( final, buf );
		    continue;
		}

		sprintf( buf, "R 0 %5d %2d        * Randomize %s\n",
			pReset->arg1,
			pReset->arg2,
			pRoomIndex->name );
		strcat( final, buf );

		break;
	}
	send_to_char( final, ch );
    }

    return;
}


void add_reset( ROOM_INDEX_DATA * room, RESET_DATA * pReset, int index )
{
    RESET_DATA *reset;
    int         iReset = 0;

    if ( !room->reset_first )
    {
	room->reset_first	= pReset;
	room->reset_last	= pReset;
	pReset->next		= NULL;
	return;
    }

    index--;

    if ( index == 0 )
    {
	pReset->next		= room->reset_first;
	room->reset_first	= pReset;
	return;
    }

    for ( reset = room->reset_first; reset->next; reset = reset->next )
    {
	if ( ++iReset == index )
	    break;
    }

    pReset->next		= reset->next;
    reset->next			= pReset;
    if ( !pReset->next )
	room->reset_last	= pReset;
    return;
}


void do_resets( CHAR_DATA * ch, char *argument )
{
    ROOM_INDEX_DATA  *pRoom;
    AREA_DATA        *pArea;
    RESET_DATA       *pReset;
    char              arg1 [ MAX_INPUT_LENGTH ];
    char              arg2 [ MAX_INPUT_LENGTH ];
    char              arg3 [ MAX_INPUT_LENGTH ];
    char              arg4 [ MAX_INPUT_LENGTH ];
    char              arg5 [ MAX_INPUT_LENGTH ];

    argument = one_argument( argument, arg1 );
    argument = one_argument( argument, arg2 );
    argument = one_argument( argument, arg3 );
    argument = one_argument( argument, arg4 );
    argument = one_argument( argument, arg5 );

    pReset = NULL;
    pRoom  = ch->in_room;
    pArea  = pRoom->area;

    if ( !is_builder( ch, pArea ) )
    {
	send_to_char( "Invalid security for editing this area.\n\r", ch );
	return;
    }


    if ( arg1[0] == '\0' )
    {
	if ( pRoom->reset_first )
	{
	    send_to_char( "Resets: M = mobile, R = room, ",        ch );
	    send_to_char( "O = object, P = pet, S = shopkeeper\n\r", ch );
	    display_resets( ch );
	}
	else
	    send_to_char( "There are no resets in this room.\n\r", ch );

	return;
    }


    if ( !is_number( arg1 ) )
    {
	send_to_char( "Syntax: reset  <number>  obj     <vnum>  <wearloc>        \n\r", ch );
	send_to_char( "or:     reset  <number>  obj     <vnum>  room             \n\r", ch );
	send_to_char( "or:     reset  <number>  obj     <vnum>  in         <vnum>\n\r", ch );
	send_to_char( "or:     reset  <number>  mob     <vnum>                   \n\r", ch );
	send_to_char( "or:     reset  <number>  mob     <vnum>  <max num>        \n\r", ch );
	send_to_char( "or:     reset  <number>  delete                           \n\r", ch );
	return;
    }

    if ( !str_cmp( arg2, "delete" ) )
    {
	int insert_loc = atoi( arg1 );

	if ( !pRoom->reset_first )
	{
	    send_to_char( "There are no resets in this area.\n\r", ch );
	    return;
	}

	if ( insert_loc - 1 <= 0 )
	{
	    pReset = pRoom->reset_first;
	    pRoom->reset_first = pRoom->reset_first->next;
	    if ( !pRoom->reset_first )
		pRoom->reset_last = NULL;
	}
	else
	{
	    RESET_DATA *prev   = NULL;
	    int         iReset = 0;

	    for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
	    {
		if ( ++iReset == insert_loc )
		    break;
		prev = pReset;
	    }

	    if ( !pReset )
	    {
		send_to_char( "Reset not found.\n\r", ch );
		return;
	    }

	    if ( prev )
		prev->next = prev->next->next;
	    else
		pRoom->reset_first = pRoom->reset_first->next;

	    for ( pRoom->reset_last = pRoom->reset_first;
		 pRoom->reset_last->next;
		 pRoom->reset_last = pRoom->reset_last->next );
	}

	free_reset_data( pReset );
	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Reset deleted.\n\r", ch );
	return;
    }

    if ( ( !str_cmp( arg2, "mob" ) || !str_cmp( arg2, "obj" ) )
	&& is_number( arg3 ) )
    {
	if ( !str_cmp( arg2, "mob" ) )
	{
	    pReset          = new_reset_data( );
	    pReset->command = 'M';
	    pReset->arg1    = atoi( arg3 );
	    pReset->arg2    = is_number( arg4 ) ? atoi( arg4 ) : 1;
	    pReset->arg3    = pRoom->vnum;
	}
	else
	if ( !str_cmp( arg2, "obj" ) )
	{
	    pReset       = new_reset_data( );
	    pReset->arg1 = atoi( arg3 );

	    if ( !str_prefix( arg4, "inside" ) )
	    {
		pReset->command = 'P';
		pReset->arg2    = 0;
		pReset->arg3    = is_number( arg5 ) ? atoi( arg5 ) : 1;
	    }
	    else
	    if ( !str_cmp( arg4, "room" ) )
	    {
		pReset->command = 'O';
		pReset->arg1    = atoi( arg3 );
		pReset->arg2    = 0;
		pReset->arg3    = pRoom->vnum;
	    }
	    else
	    {
		if ( flag_value( wear_loc_flags, arg4 ) == NO_FLAG )
		{
		    send_to_char( "Resets: '? wear-loc'\n\r", ch );
		    return;
		}

		pReset->arg3 = flag_value( wear_loc_flags, arg4 );

		if ( pReset->arg3 == WEAR_NONE )
		    pReset->command = 'G';
		else
		    pReset->command = 'E';
	    }
	}

	add_reset( pRoom, pReset, atoi( arg1 ) );
	SET_BIT( pArea->area_flags, AREA_CHANGED );
	send_to_char( "Reset added.\n\r", ch );
    }

    return;
}


void do_alist( CHAR_DATA * ch, char *argument )
{
    AREA_DATA *pArea;
    char       buf  [MAX_STRING_LENGTH];
    char       buf1 [MAX_STRING_LENGTH*2];

    buf1[0] = '\0';

    sprintf( buf, "[%3s] [%-27s] [%-5s/%5s] [%-10s] %3s [%-10s]\n\r",
    "Num", "Area Name", "lvnum", "uvnum", "Filename", "Sec", "Builders" );
    strcat( buf1, buf );

    for ( pArea = area_first; pArea; pArea = pArea->next )
    {
	sprintf( buf, "[%3d] %-7.7s %-21.21s [%5d/%-5d] %-12.12s [%1.1d] [%-10.10s]\n\r",
		pArea->vnum,
		pArea->author,
		pArea->name,
		pArea->lvnum,
		pArea->uvnum,
		pArea->filename,
		pArea->security,
		pArea->builders );
	strcat( buf1, buf );
    }
    send_to_char( buf1, ch );

    return;
}