📄 mob_prog.c
字号:
else
return -1;
case 'r': if ( rndm )
{
if IS_NPC( actor )
{
lhsvl = rndm->pIndexData->vnum;
rhsvl = atoi( val );
return mprog_veval( lhsvl, opr, rhsvl );
}
}
else return -1;
case 'o': if ( obj )
{
lhsvl = obj->pIndexData->vnum;
rhsvl = atoi( val );
return mprog_veval( lhsvl, opr, rhsvl );
}
else
return -1;
case 'p': if ( v_obj )
{
lhsvl = v_obj->pIndexData->vnum;
rhsvl = atoi( val );
return mprog_veval( lhsvl, opr, rhsvl );
}
else
return -1;
default:
bug ( "Mob: %d bad argument to 'number'", mob->pIndexData->vnum );
return -1;
}
}
if ( !str_cmp( buf, "name" ) )
{
switch ( arg[1] ) /* arg should be "$*" so just get the letter */
{
case 'i': return mprog_seval( mob->name, opr, val );
case 'n': if ( actor )
return mprog_seval( actor->name, opr, val );
else
return -1;
case 't': if ( vict )
return mprog_seval( vict->name, opr, val );
else
return -1;
case 'r': if ( rndm )
return mprog_seval( rndm->name, opr, val );
else
return -1;
case 'o': if ( obj )
return mprog_seval( obj->name, opr, val );
else
return -1;
case 'p': if ( v_obj )
return mprog_seval( v_obj->name, opr, val );
else
return -1;
default:
bug ( "Mob: %d bad argument to 'name'", mob->pIndexData->vnum );
return -1;
}
}
/* Ok... all the ifchcks are done, so if we didnt find ours then something
* odd happened. So report the bug and abort the MOBprogram (return error)
*/
bug ( "Mob: %d unknown ifchck", mob->pIndexData->vnum );
return -1;
}
/* Quite a long and arduous function, this guy handles the control
* flow part of MOBprograms. Basicially once the driver sees an
* 'if' attention shifts to here. While many syntax errors are
* caught, some will still get through due to the handling of break
* and errors in the same fashion. The desire to break out of the
* recursion without catastrophe in the event of a mis-parse was
* believed to be high. Thus, if an error is found, it is bugged and
* the parser acts as though a break were issued and just bails out
* at that point. I havent tested all the possibilites, so I'm speaking
* in theory, but it is 'guaranteed' to work on syntactically correct
* MOBprograms, so if the mud crashes here, check the mob carefully!
*/
char *mprog_process_if( char *ifchck, char *com_list, CHAR_DATA *mob,
CHAR_DATA *actor, OBJ_DATA *obj, void *vo,
CHAR_DATA *rndm )
{
char null[ 1 ];
char buf[ MAX_INPUT_LENGTH ];
char *morebuf = '\0';
char *cmnd = '\0';
bool loopdone = FALSE;
bool flag = FALSE;
int legal;
*null = '\0';
/* check for trueness of the ifcheck */
if ( ( legal = mprog_do_ifchck( ifchck, mob, actor, obj, vo, rndm ) ) )
if ( legal == 1 )
flag = TRUE;
else
return null;
while( loopdone == FALSE ) /*scan over any existing or statements */
{
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob: %d no commands after IF/OR", mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd, buf );
if ( !str_cmp( buf, "or" ) )
{
if ( ( legal = mprog_do_ifchck( morebuf,mob,actor,obj,vo,rndm ) ) )
if ( legal == 1 )
flag = TRUE;
else
return null;
}
else
loopdone = TRUE;
}
if ( flag )
for ( ; ; ) /*ifcheck was true, do commands but ignore else to endif*/
{
if ( !str_cmp( buf, "if" ) )
{
com_list = mprog_process_if(morebuf,com_list,mob,actor,obj,vo,rndm);
while ( *cmnd==' ' )
cmnd++;
if ( *com_list == '\0' )
return null;
cmnd = com_list;
com_list = mprog_next_command( com_list );
morebuf = one_argument( cmnd,buf );
continue;
}
if ( !str_cmp( buf, "break" ) )
return null;
if ( !str_cmp( buf, "endif" ) )
return com_list;
if ( !str_cmp( buf, "else" ) )
{
while ( str_cmp( buf, "endif" ) )
{
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob: %d missing endif after else",
mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd,buf );
}
return com_list;
}
mprog_process_cmnd( cmnd, mob, actor, obj, vo, rndm );
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob: %d missing else or endif", mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd, buf );
}
else /*false ifcheck, find else and do existing commands or quit at endif*/
{
while ( ( str_cmp( buf, "else" ) ) && ( str_cmp( buf, "endif" ) ) )
{
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob: %d missing an else or endif",
mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd, buf );
}
/* found either an else or an endif.. act accordingly */
if ( !str_cmp( buf, "endif" ) )
return com_list;
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob: %d missing endif", mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd, buf );
for ( ; ; ) /*process the post-else commands until an endif is found.*/
{
if ( !str_cmp( buf, "if" ) )
{
com_list = mprog_process_if( morebuf, com_list, mob, actor,
obj, vo, rndm );
while ( *cmnd == ' ' )
cmnd++;
if ( *com_list == '\0' )
return null;
cmnd = com_list;
com_list = mprog_next_command( com_list );
morebuf = one_argument( cmnd,buf );
continue;
}
if ( !str_cmp( buf, "else" ) )
{
bug ( "Mob: %d found else in an else section",
mob->pIndexData->vnum );
return null;
}
if ( !str_cmp( buf, "break" ) )
return null;
if ( !str_cmp( buf, "endif" ) )
return com_list;
mprog_process_cmnd( cmnd, mob, actor, obj, vo, rndm );
cmnd = com_list;
com_list = mprog_next_command( com_list );
while ( *cmnd == ' ' )
cmnd++;
if ( *cmnd == '\0' )
{
bug ( "Mob:%d missing endif in else section",
mob->pIndexData->vnum );
return null;
}
morebuf = one_argument( cmnd, buf );
}
}
}
/* This routine handles the variables for command expansion.
* If you want to add any go right ahead, it should be fairly
* clear how it is done and they are quite easy to do, so you
* can be as creative as you want. The only catch is to check
* that your variables exist before you use them. At the moment,
* using $t when the secondary target refers to an object
* i.e. >prog_act drops~<nl>if ispc($t)<nl>sigh<nl>endif<nl>~<nl>
* probably makes the mud crash (vice versa as well) The cure
* would be to change act() so that vo becomes vict & v_obj.
* but this would require a lot of small changes all over the code.
*/
void mprog_translate( char ch, char *t, CHAR_DATA *mob, CHAR_DATA *actor,
OBJ_DATA *obj, void *vo, CHAR_DATA *rndm )
{
static char *he_she [] = { "it", "he", "she" };
static char *him_her [] = { "it", "him", "her" };
static char *his_her [] = { "its", "his", "her" };
CHAR_DATA *vict = (CHAR_DATA *) vo;
OBJ_DATA *v_obj = (OBJ_DATA *) vo;
*t = '\0';
switch ( ch ) {
case 'i':
one_argument( mob->name, t );
break;
case 'I':
strcpy( t, mob->short_descr );
break;
case 'n':
if ( actor )
if ( can_see( mob,actor ) )
one_argument( actor->name, t );
if ( !IS_NPC( actor ) )
*t = UPPER( *t );
break;
case 'N':
if ( actor )
if ( can_see( mob, actor ) )
if ( IS_NPC( actor ) )
strcpy( t, actor->short_descr );
else
{
strcpy( t, actor->name );
strcat( t, " " );
strcat( t, actor->pcdata->title );
}
else
strcpy( t, "someone" );
break;
case 't':
if ( vict )
if ( can_see( mob, vict ) )
one_argument( vict->name, t );
if ( !IS_NPC( vict ) )
*t = UPPER( *t );
break;
case 'T':
if ( vict )
if ( can_see( mob, vict ) )
if ( IS_NPC( vict ) )
strcpy( t, vict->short_descr );
else
{
strcpy( t, vict->name );
strcat( t, " " );
strcat( t, vict->pcdata->title );
}
else
strcpy( t, "someone" );
break;
case 'r':
if ( rndm )
if ( can_see( mob, rndm ) )
one_argument( rndm->name, t );
if ( !IS_NPC( rndm ) )
*t = UPPER( *t );
break;
case 'R':
if ( rndm )
if ( can_see( mob, rndm ) )
if ( IS_NPC( rndm ) )
strcpy(t,rndm->short_descr);
else
{
strcpy( t, rndm->name );
strcat( t, " " );
strcat( t, rndm->pcdata->title );
}
else
strcpy( t, "someone" );
break;
case 'e':
if ( actor )
can_see( mob, actor ) ? strcpy( t, he_she[ actor->sex ] )
: strcpy( t, "someone" );
break;
case 'm':
if ( actor )
can_see( mob, actor ) ? strcpy( t, him_her[ actor->sex ] )
: strcpy( t, "someone" );
break;
case 's':
if ( actor )
can_see( mob, actor ) ? strcpy( t, his_her[ actor->sex ] )
: strcpy( t, "someone's" );
break;
case 'E':
if ( vict )
can_see( mob, vict ) ? strcpy( t, he_she[ vict->sex ] )
: strcpy( t, "someone" );
break;
case 'M':
if ( vict )
can_see( mob, vict ) ? strcpy( t, him_her[ vict->sex ] )
: strcpy( t, "someone" );
break;
case 'S':
if ( vict )
can_see( mob, vict ) ? strcpy( t, his_her[ vict->sex ] )
: strcpy( t, "someone's" );
break;
case 'j':
strcpy( t, he_she[ mob->sex ] );
break;
case 'k':
strcpy( t, him_her[ mob->sex ] );
break;
case 'l':
strcpy( t, his_her[ mob->sex ] );
break;
case 'J':
if ( rndm )
can_see( mob, rndm ) ? strcpy( t, he_she[ rndm->sex ] )
: strcpy( t, "someone" );
break;
case 'K':
if ( rndm )
can_see( mob, rndm ) ? strcpy( t, him_her[ rndm->sex ] )
: strcpy( t, "someone" );
break;
case 'L':
if ( rndm )
can_see( mob, rndm ) ? strcpy( t, his_her[ rndm->sex ] )
: strcpy( t, "someone's" );
break;
case 'o':
if ( obj )
can_see_obj( mob, obj ) ? one_argument( obj->name, t )
: strcpy( t, "something" );
break;
case 'O':
if ( obj )
can_see_obj( mob, obj ) ? strcpy( t, obj->short_descr )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -