📄 mob_prog.c
字号:
: strcpy( t, "something" );
break;
case 'p':
if ( v_obj )
can_see_obj( mob, v_obj ) ? one_argument( v_obj->name, t )
: strcpy( t, "something" );
break;
case 'P':
if ( v_obj )
can_see_obj( mob, v_obj ) ? strcpy( t, v_obj->short_descr )
: strcpy( t, "something" );
break;
case 'a':
if ( obj )
switch ( *( obj->name ) )
{
case 'a': case 'e': case 'i':
case 'o': case 'u': strcpy( t, "an" );
break;
default: strcpy( t, "a" );
}
break;
case 'A':
if ( v_obj )
switch ( *( v_obj->name ) )
{
case 'a': case 'e': case 'i':
case 'o': case 'u': strcpy( t, "an" );
break;
default: strcpy( t, "a" );
}
break;
case '$':
strcpy( t, "$" );
break;
default:
bug( "Mob: %d bad $var", mob->pIndexData->vnum );
break;
}
return;
}
/* This procedure simply copies the cmnd to a buffer while expanding
* any variables by calling the translate procedure. The observant
* code scrutinizer will notice that this is taken from act()
*/
void mprog_process_cmnd( char *cmnd, CHAR_DATA *mob, CHAR_DATA *actor,
OBJ_DATA *obj, void *vo, CHAR_DATA *rndm )
{
char buf[ MAX_INPUT_LENGTH ];
char tmp[ MAX_INPUT_LENGTH ];
char *str;
char *i;
char *point;
point = buf;
str = cmnd;
while ( *str != '\0' )
{
if ( *str != '$' )
{
*point++ = *str++;
continue;
}
str++;
mprog_translate( *str, tmp, mob, actor, obj, vo, rndm );
i = tmp;
++str;
while ( ( *point = *i ) != '\0' )
++point, ++i;
}
*point = '\0';
interpret( mob, buf );
return;
}
/* The main focus of the MOBprograms. This routine is called
* whenever a trigger is successful. It is responsible for parsing
* the command list and figuring out what to do. However, like all
* complex procedures, everything is farmed out to the other guys.
*/
void mprog_driver ( char *com_list, CHAR_DATA *mob, CHAR_DATA *actor,
OBJ_DATA *obj, void *vo)
{
char tmpcmndlst[ MAX_STRING_LENGTH ];
char buf [ MAX_INPUT_LENGTH ];
char *morebuf;
char *command_list;
char *cmnd;
CHAR_DATA *rndm = NULL;
CHAR_DATA *vch = NULL;
int count = 0;
if IS_AFFECTED( mob, AFF_CHARM )
return;
/* get a random visable mortal player who is in the room with the mob */
for ( vch = mob->in_room->people; vch; vch = vch->next_in_room )
if ( !IS_NPC( vch )
&& vch->level < LEVEL_IMMORTAL
&& can_see( mob, vch ) )
{
if ( number_range( 0, count ) == 0 )
rndm = vch;
count++;
}
strcpy( tmpcmndlst, com_list );
command_list = tmpcmndlst;
cmnd = command_list;
command_list = mprog_next_command( command_list );
while ( *cmnd != '\0' )
{
morebuf = one_argument( cmnd, buf );
if ( !str_cmp( buf, "if" ) )
command_list = mprog_process_if( morebuf, command_list, mob,
actor, obj, vo, rndm );
else
mprog_process_cmnd( cmnd, mob, actor, obj, vo, rndm );
cmnd = command_list;
command_list = mprog_next_command( command_list );
}
return;
}
/***************************************************************************
* Global function code and brief comments.
*/
/* The next two routines are the basic trigger types. Either trigger
* on a certain percent, or trigger on a keyword or word phrase.
* To see how this works, look at the various trigger routines..
*/
void mprog_wordlist_check( char *arg, CHAR_DATA *mob, CHAR_DATA *actor,
OBJ_DATA *obj, void *vo, int type )
{
char temp1[ MAX_STRING_LENGTH ];
char temp2[ MAX_INPUT_LENGTH ];
char word[ MAX_INPUT_LENGTH ];
MPROG_DATA *mprg;
char *list;
char *start;
char *dupl;
char *end;
int i;
for ( mprg = mob->pIndexData->mobprogs; mprg != NULL; mprg = mprg->next )
if ( mprg->type & type )
{
strcpy( temp1, mprg->arglist );
list = temp1;
for ( i = 0; i < strlen( list ); i++ )
list[i] = LOWER( list[i] );
strcpy( temp2, arg );
dupl = temp2;
for ( i = 0; i < strlen( dupl ); i++ )
dupl[i] = LOWER( dupl[i] );
if ( ( list[0] == 'p' ) && ( list[1] == ' ' ) )
{
list += 2;
while ( ( start = strstr( dupl, list ) ) )
if ( (start == dupl || *(start-1) == ' ' )
&& ( *(end = start + strlen( list ) ) == ' '
|| *end == '\n'
|| *end == '\r'
|| *end == '\0' ) )
{
mprog_driver( mprg->comlist, mob, actor, obj, vo );
break;
}
else
dupl = start+1;
}
else
{
list = one_argument( list, word );
for( ; word[0] != '\0'; list = one_argument( list, word ) )
while ( ( start = strstr( dupl, word ) ) )
if ( ( start == dupl || *(start-1) == ' ' )
&& ( *(end = start + strlen( word ) ) == ' '
|| *end == '\n'
|| *end == '\r'
|| *end == '\0' ) )
{
mprog_driver( mprg->comlist, mob, actor, obj, vo );
break;
}
else
dupl = start+1;
}
}
return;
}
void mprog_percent_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj,
void *vo, int type)
{
MPROG_DATA * mprg;
for ( mprg = mob->pIndexData->mobprogs; mprg != NULL; mprg = mprg->next )
if ( ( mprg->type & type )
&& ( number_percent( ) < atoi( mprg->arglist ) ) )
{
mprog_driver( mprg->comlist, mob, actor, obj, vo );
if ( type != GREET_PROG && type != ALL_GREET_PROG )
break;
}
return;
}
/* The triggers.. These are really basic, and since most appear only
* once in the code (hmm. i think they all do) it would be more efficient
* to substitute the code in and make the mprog_xxx_check routines global.
* However, they are all here in one nice place at the moment to make it
* easier to see what they look like. If you do substitute them back in,
* make sure you remember to modify the variable names to the ones in the
* trigger calls.
*/
void mprog_act_trigger( char *buf, CHAR_DATA *mob, CHAR_DATA *ch,
OBJ_DATA *obj, void *vo)
{
MPROG_ACT_LIST * tmp_act;
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & ACT_PROG ) )
{
tmp_act = alloc_mem( sizeof( MPROG_ACT_LIST ) );
if ( mob->mpactnum > 0 )
tmp_act->next = mob->mpact->next;
else
tmp_act->next = NULL;
mob->mpact = tmp_act;
mob->mpact->buf = str_dup( buf );
mob->mpact->ch = ch;
mob->mpact->obj = obj;
mob->mpact->vo = vo;
mob->mpactnum++;
}
return;
}
void mprog_bribe_trigger( CHAR_DATA *mob, CHAR_DATA *ch, int amount )
{
char buf[ MAX_STRING_LENGTH ];
MPROG_DATA *mprg;
OBJ_DATA *obj;
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & BRIBE_PROG ) )
{
obj = create_object( get_obj_index( OBJ_VNUM_MONEY_SOME ), 0 );
sprintf( buf, obj->short_descr, amount );
free_string( obj->short_descr );
obj->short_descr = str_dup( buf );
obj->value[0] = amount;
obj_to_char( obj, mob );
mob->gold -= amount;
for ( mprg = mob->pIndexData->mobprogs; mprg != NULL; mprg = mprg->next )
if ( ( mprg->type & BRIBE_PROG )
&& ( amount >= atoi( mprg->arglist ) ) )
{
mprog_driver( mprg->comlist, mob, ch, obj, NULL );
break;
}
}
return;
}
void mprog_death_trigger( CHAR_DATA *mob )
{
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & DEATH_PROG ) )
{
mprog_percent_check( mob, NULL, NULL, NULL, DEATH_PROG );
}
death_cry( mob );
return;
}
void mprog_entry_trigger( CHAR_DATA *mob )
{
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & ENTRY_PROG ) )
mprog_percent_check( mob, NULL, NULL, NULL, ENTRY_PROG );
return;
}
void mprog_fight_trigger( CHAR_DATA *mob, CHAR_DATA *ch )
{
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & FIGHT_PROG ) )
mprog_percent_check( mob, ch, NULL, NULL, FIGHT_PROG );
return;
}
void mprog_give_trigger( CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj )
{
char buf[MAX_INPUT_LENGTH];
MPROG_DATA *mprg;
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & GIVE_PROG ) )
for ( mprg = mob->pIndexData->mobprogs; mprg != NULL; mprg = mprg->next )
{
one_argument( mprg->arglist, buf );
if ( ( mprg->type & GIVE_PROG )
&& ( ( !str_cmp( obj->name, mprg->arglist ) )
|| ( !str_cmp( "all", buf ) ) ) )
{
mprog_driver( mprg->comlist, mob, ch, obj, NULL );
break;
}
}
return;
}
void mprog_greet_trigger( CHAR_DATA *mob )
{
CHAR_DATA *vmob;
for ( vmob = mob->in_room->people; vmob != NULL; vmob = vmob->next_in_room )
if ( IS_NPC( vmob )
&& mob != vmob
&& can_see( vmob, mob )
&& ( vmob->fighting == NULL )
&& IS_AWAKE( vmob )
&& ( vmob->pIndexData->progtypes & GREET_PROG) )
mprog_percent_check( vmob, mob, NULL, NULL, GREET_PROG );
else
if ( IS_NPC( vmob )
&& ( vmob->fighting == NULL )
&& IS_AWAKE( vmob )
&& ( vmob->pIndexData->progtypes & ALL_GREET_PROG ) )
mprog_percent_check( vmob, mob, NULL, NULL, ALL_GREET_PROG );
return;
}
void mprog_hitprcnt_trigger( CHAR_DATA *mob, CHAR_DATA *ch)
{
MPROG_DATA *mprg;
if ( IS_NPC( mob )
&& ( mob->pIndexData->progtypes & HITPRCNT_PROG ) )
for ( mprg = mob->pIndexData->mobprogs; mprg != NULL; mprg = mprg->next )
if ( ( mprg->type & HITPRCNT_PROG )
&& ( ( 100*mob->hit / mob->max_hit ) < atoi( mprg->arglist ) ) )
{
mprog_driver( mprg->comlist, mob, ch, NULL, NULL );
break;
}
return;
}
void mprog_random_trigger( CHAR_DATA *mob )
{
if ( mob->pIndexData->progtypes & RAND_PROG)
mprog_percent_check(mob,NULL,NULL,NULL,RAND_PROG);
return;
}
void mprog_speech_trigger( char *txt, CHAR_DATA *mob )
{
CHAR_DATA *vmob;
for ( vmob = mob->in_room->people; vmob != NULL; vmob = vmob->next_in_room )
if ( IS_NPC( vmob ) && ( vmob->pIndexData->progtypes & SPEECH_PROG ) )
mprog_wordlist_check( txt, vmob, mob, NULL, NULL, SPEECH_PROG );
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -