/* The following code is based on ILAB OLC by Jason Dinkel */
/* Mobprogram code by Lordrom for Nevermore Mud */
/* Object and Room Progs added by SpiralSOFT! */
#include <glib.h>
#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 <tables.h>
#include <olc.h>
#include <recycle.h>
#define MPEDIT( fun ) bool fun(CHAR_DATA *ch, char*argument)
bool find_objmob(CHAR_DATA *mob, OBJ_INDEX_DATA *pObjIndex)
{
OBJ_DATA *obj;
for (obj = mob->carrying; obj != NULL; obj = obj->next_content )
{
if (obj->pIndexData == pObjIndex)
return TRUE;
}
return FALSE;
}
/* OLC
* Reset one room. Called by reset_area and olc.
*/
void reset_room( ROOM_INDEX_DATA *pRoom )
{
RESET_DATA *pReset;
GSList *ResetList;
CHAR_DATA *pMob;
/* CHAR_DATA *mob; */
OBJ_DATA *pObj;
CHAR_DATA *LastMob = NULL;
OBJ_DATA *LastObj = NULL;
int iExit;
int level = 0;
bool last;
if ( !pRoom )
return;
/*pMob = NULL; */
last = FALSE;
for ( iExit = 0; iExit < MAX_DIR; iExit++ )
{
EXIT_DATA *pExit;
if ( ( pExit = pRoom->exit[iExit] )
/* && !IS_SET( pExit->exit_info, EX_BASHED ) ROM OLC */ )
{
pExit->exit_info = pExit->rs_flags;
if ( ( pExit->to_room != NULL )
&& ( ( pExit = pExit->to_room->exit[rev_dir[iExit]] ) ) )
{
/* nail the other side */
pExit->exit_info = pExit->rs_flags;
}
}
}
for ( ResetList = pRoom->reset_list; ResetList != NULL; ResetList = g_slist_next(ResetList) )
{
MOB_INDEX_DATA *pMobIndex;
OBJ_INDEX_DATA *pObjIndex;
ROOM_INDEX_DATA *pRoomIndexPrev;
OBJ_INDEX_DATA *pObjToIndex;
ROOM_INDEX_DATA *pRoomIndex;
char buf[MAX_STRING_LENGTH];
int count=0;
pReset = (RESET_DATA*)ResetList->data;
switch ( pReset->command )
{
default:
bug( "Reset_room: bad command %c.", pReset->command );
break;
case 'M':
if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'M': bad vnum %d.", pReset->arg1 );
continue;
}
if ( ( pRoomIndex = get_room_index( pReset->arg3 ) ) == NULL )
{
bug( "Reset_area: 'R': bad vnum %d.", pReset->arg3 );
continue;
}
if ( pMobIndex->count >= pReset->arg2 )
{
last = FALSE;
break;
}
pMob = create_mobile( pMobIndex );
/*
* Pet shop mobiles get ACT_PET set.
*/
pRoomIndexPrev = get_room_index( pRoomIndex->vnum - 1 );
if ( pRoomIndexPrev
&& IS_SET( pRoomIndexPrev->room_flags, ROOM_PET_SHOP ) )
SET_BIT( pMob->act, ACT_PET);
char_to_room( pMob, pRoomIndex );
LastMob = pMob;
level = URANGE( 0, pMob->level - 2, LEVEL_HERO - 1 ); /* -1 ROM */
last = TRUE;
break;
case 'O':
if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'O' 1 : bad vnum %d", pReset->arg1 );
sprintf (buf,"%d %d %d %d",pReset->arg1, pReset->arg2, pReset->arg3,
pReset->arg4 );
bug(buf,1);
continue;
}
if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
{
bug( "Reset_room: 'O' 2 : bad vnum %d.", pReset->arg3 );
sprintf (buf,"%d %d %d %d",pReset->arg1, pReset->arg2, pReset->arg3,
pReset->arg4 );
bug(buf,1);
continue;
}
if ( pRoomIndex->area->nplayer > 0
|| count_obj_list( pObjIndex, pRoomIndex->contents ) > 0 )
{
last = FALSE;
break;
}
pObj = create_object( pObjIndex,number_range(1,50) );
pObj->cost = 0;
obj_to_room( pObj, pRoomIndex );
last = TRUE;
break;
case 'P':
if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'P': bad vnum %d.", pReset->arg1 );
continue;
}
if ( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) )
{
bug( "Reset_room: 'P': bad vnum %d.", pReset->arg3 );
continue;
}
if ( pRoom->area->nplayer > 0
|| !( LastObj = get_obj_type( pObjToIndex ) )
/* || ( LastObj->in_room == NULL && !last)
|| ( pObjIndex->count >= limit && number_range(0,4) != 0 )
|| ( count = count_obj_list( pObjIndex, LastObj->contains ) ) > pReset->arg4 )
*/
|| ( count = count_obj_list( pObjIndex, LastObj->contains ) ) > pReset->arg4 )
{
last = FALSE;
break;
}
/* lastObj->level - ROM */
pObj = create_object( pObjIndex, number_range(1,50) );
obj_to_obj( pObj, LastObj );
last = TRUE;
break;
case 'G':
case 'E':
if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'E' or 'G': bad vnum %d.", pReset->arg1 );
continue;
}
if ( !last )
break;
if ( !LastMob )
{
bug( "Reset_room: 'E' or 'G': null mob for vnum %d.",
pReset->arg1 );
last = FALSE;
break;
}
/*
* Check mobile if they don't already have said eq..
*/
if (find_objmob(LastMob, pObjIndex))
continue;
if ( LastMob->pIndexData->pShop ) /* Shop-keeper? */
{
int olevel=0;
switch ( pObjIndex->item_type )
{
default: olevel = 0; break;
case ITEM_PILL: olevel = number_range( 0,10); break;
case ITEM_POTION: olevel = number_range( 0,10); break;
case ITEM_SCROLL: olevel = number_range( 5,15); break;
case ITEM_WAND: olevel = number_range( 10, 20 ); break;
case ITEM_STAFF: olevel = number_range( 15, 25 ); break;
case ITEM_ARMOR: olevel = number_range( 5, 15 ); break;
case ITEM_WEAPON: olevel = number_range( 5, 15 ); break;
}
pObj = create_object( pObjIndex, olevel );
SET_BIT( pObj->extra_flags, ITEM_INVENTORY ); /* ROM OLC */
}
else /* ROM OLC else version */
{
pObj = create_object( pObjIndex, number_range( 1,50));
}
obj_to_char( pObj, LastMob );
if ( pReset->command == 'E' )
equip_char( LastMob, pObj, pReset->arg3 );
last = TRUE;
break;
case 'D':
break;
case 'R':
if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
{
bug( "Reset_room: 'R': bad vnum %d.", pReset->arg1 );
continue;
}
{
EXIT_DATA *pExit;
int d0;
int d1;
for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ )
{
d1 = number_range( d0, pReset->arg2-1 );
pExit = pRoomIndex->exit[d0];
pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
pRoomIndex->exit[d1] = pExit;
}
}
break;
}
}
return;
}
/* OLC
* Reset one area.
*/
void reset_area( AREA_DATA *pArea )
{
ROOM_INDEX_DATA *pRoom;
int vnum;
for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
{
if ( ( pRoom = get_room_index(vnum) ) )
{
reset_room(pRoom);
}
}
return;
}
const struct olc_cmd_type mpedit_table[] =
{
/* { command function }, */
{ "commands", show_commands },
{ "create", mpedit_create },
{ "code", mpedit_code },
{ "show", mpedit_show },
{ "list", mpedit_list },
{ "?", show_help },
{ NULL, 0 }
};
void mpedit( CHAR_DATA *ch, char *argument)
{
MPROG_CODE *pMcode;
char arg[MAX_INPUT_LENGTH];
char command[MAX_INPUT_LENGTH];
int cmd;
AREA_DATA *ad;
smash_tilde(argument);
str_cpy(arg, argument);
argument = one_argument( argument, command);
EDIT_MPCODE(ch, pMcode);
if (pMcode)
{
ad = get_vnum_area( pMcode->vnum );
if ( ad == NULL ) /* ??? */
{
edit_done(ch);
return;
}
if ( !IS_BUILDER(ch, ad) )
{
send_to_char("MPEdit: Insufficient security to modify code.\n\r", ch);
edit_done(ch);
return;
}
}
if (command[0] == '\0')
{
mpedit_show(ch, argument);
return;
}
if (!str_cmp(command, "done") )
{
edit_done(ch);
return;
}
for (cmd = 0; mpedit_table[cmd].name != NULL; cmd++)
{
if (!str_prefix(command, mpedit_table[cmd].name) )
{
if ((*mpedit_table[cmd].olc_fun) (ch, argument) && pMcode)
if ((ad = get_vnum_area(pMcode->vnum)) != NULL)
SET_BIT(ad->area_flags, AREA_CHANGED);
return;
}
}
interpret(ch, arg);
return;
}
void do_mpedit(CHAR_DATA *ch, char *argument)
{
MPROG_CODE *pMcode;
char command[MAX_INPUT_LENGTH];
argument = one_argument(argument, command);
if( is_number(command) )
{
int vnum = atoi(command);
AREA_DATA *ad;
if ( (pMcode = get_mprog_index(vnum)) == NULL )
{
send_to_char("MPEdit : That vnum does not exist.\n\r",ch);
return;
}
ad = get_vnum_area(vnum);
if ( ad == NULL )
{
send_to_char( "MPEdit : VNUM is not assigned to this area.\n\r", ch );
return;
}
if ( !IS_BUILDER(ch, ad) )
{
send_to_char("MPEdit : Insufficient security to edit this area.\n\r", ch );
return;
}
ch->desc->pEdit = (void *)pMcode;
ch->desc->editor = ED_MPCODE;
return;
}
if ( !str_cmp(command, "create") )
{
if (argument[0] == '\0')
{
send_to_char( "Sintax : mpedit create [vnum]\n\r", ch );
return;
}
mpedit_create(ch, argument);
return;
}
send_to_char( "Sintax : mpedit [vnum]\n\r", ch );
send_to_char( " mpedit create [vnum]\n\r", ch );
return;
}
MPEDIT (mpedit_create)
{
MPROG_CODE *pMcode;
int value = atoi(argument);
AREA_DATA *ad;
if (IS_NULLSTR(argument) || value < 1)
{
send_to_char( "Sintax : mpedit create [vnum]\n\r", ch );
return FALSE;
}
ad = get_vnum_area(value);
if ( ad == NULL )
{
send_to_char( "MPEdit : VNUM not assigned to this area.\n\r", ch );
return FALSE;
}
if ( !IS_BUILDER(ch, ad) )
{
send_to_char("MPEdit : Insufficient security to create MobProgs.\n\r", ch);
return FALSE;
}
if ( get_mprog_index(value) )
{
send_to_char("MPEdit: Code vnum already exists.\n\r",ch);
return FALSE;
}
pMcode = new_mpcode();
pMcode->vnum = value;
pMcode->next = mprog_list;
mprog_list = pMcode;
ch->desc->pEdit = (void *)pMcode;
ch->desc->editor = ED_MPCODE;
send_to_char("MobProgram Code Created.\n\r",ch);
return TRUE;
}
MPEDIT(mpedit_show)
{
MPROG_CODE *pMcode;
char buf[MAX_STRING_LENGTH];
EDIT_MPCODE(ch,pMcode);
sprintf(buf,
"Vnum: [%d]\n\r"
"Code:\n\r%s\n\r",
pMcode->vnum, pMcode->code->str);
send_to_char(buf, ch);
return FALSE;
}
MPEDIT(mpedit_code)
{
MPROG_CODE *pMcode;
EDIT_MPCODE(ch, pMcode);
if (argument[0] =='\0')
{
string_append(ch, &pMcode->code->str);
return TRUE;
}
send_to_char("Syntax: code\n\r",ch);
return FALSE;
}
MPEDIT( mpedit_list )
{
int count = 1;
MPROG_CODE *mprg;
char buf[MAX_STRING_LENGTH];
GString *buffer;
bool fAll = !str_cmp(argument, "all");
char blah;
AREA_DATA *ad;
buffer = g_string_new("");
for (mprg = mprog_list; mprg !=NULL; mprg = mprg->next)
if ( fAll || ENTRE(ch->in_room->area->min_vnum, mprg->vnum, ch->in_room->area->max_vnum) )
{
ad = get_vnum_area(mprg->vnum);
if ( ad == NULL )
blah = '?';
else
if ( IS_BUILDER(ch, ad) )
blah = '*';
else
blah = ' ';
sprintf(buf, "[%3d] (%c) %5d\n\r", count, blah, mprg->vnum );
buffer = g_string_append(buffer, buf);
count++;
}
if ( count == 1 )
{
if ( fAll )
buffer = g_string_append( buffer, "MobProgram does not exist.\n\r" );
else
buffer = g_string_append( buffer, "MobPrograms do not exist in this area.\n\r" );
}
page_to_char(buffer->str, ch);
g_string_free(buffer,TRUE);
return FALSE;
}