📄 special.c
字号:
while (*vnum_list)
{
nobjvnum = atoi(vnum_list);
for ( obj = victim->carrying; obj != NULL; obj = obj->next_content )
{
if ( obj->pIndexData->vnum == nobjvnum && obj->wear_loc != -1)
return obj;
}
while (*vnum_list && *vnum_list != ' ')
vnum_list++;
if (*vnum_list == ' ')
vnum_list++;
}
return 0;
}
bool spec_agg_no_object( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
struct string_cargo_struct *cls;
// OBJ_DATA *obj;
// int nobjvnum;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 2 || ch->fighting != NULL)
return FALSE;
// nobjvnum = atoi(cls->string_list[0]);
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if (!IS_NPC(victim))
if (!is_wielding(victim, cls->string_list[0]))
{
// act( "$n screams 'PROTECT THE INNOCENT!! BANZAI!!",
act( cls->string_list[1], ch, NULL, NULL, TO_ROOM );
multi_hit( ch, victim, TYPE_UNDEFINED );
return TRUE;
}
}
return FALSE;
}
bool spec_follow_mob( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
struct string_cargo_struct *cls;
OBJ_DATA *obj;
int nmobvnum;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 1 || ch->fighting != NULL || ch->master)
return FALSE;
nmobvnum = atoi(cls->string_list[0]);
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if (IS_NPC(victim) && victim->pIndexData->vnum == nmobvnum)
{
add_follower( ch, victim );
break;
}
}
return FALSE;
}
struct char_cargo_struct {
int timer;
int state;
};
/*
Blight-generator: Makes mobs aggressive. (Ages... starts out as some kind
of low-level and when it gets to high level it changes its descr and
starts up.--maybe)
*/
// @@@ Modify this to take a list...
bool spec_generator( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
struct string_cargo_struct *cls;
OBJ_DATA *obj;
struct char_cargo_struct *mobcargo = ch->cargo;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
/* If this mob is freshly popped, initialize the character cargo */
if (mobcargo == 0)
{
mobcargo = ch->cargo = calloc(1, sizeof (struct char_cargo_struct));
mobcargo->timer = 0;
mobcargo->state = 0;
}
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 1 || ch->fighting != NULL)
return FALSE;
if (mobcargo->state < cls->ncount-1)
{
if (mobcargo->timer++ >= 10)
{
char buf[128];
sprintf(buf, "New state is %d", ++mobcargo->state); // @@@
free_string( ch->description );
ch->description = str_dup( buf );
act( "You here the sound of stretching and tearing.",
ch, NULL, NULL, TO_ROOM );
ch->level += 30 / cls->ncount + 1;
ch->max_hit = ch->level * 8 + number_range(
ch->level * ch->level / 4,
ch->level * ch->level );
mobcargo->timer = 0;
}
}
else
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if (IS_NPC(victim) && !saves_spell(ch->level, victim))
{
victim->act |= ACT_AGGRESSIVE;
victim->act &= ~ACT_WIMPY; /* Add Super-Wimp if desired */
victim->alignment = -1000;
}
}
return FALSE;
}
/*
Blight-fighter: A cityguard that attacks aggressive mobs.
*/
// @@@ Modify this to take a list...
bool spec_defend_vs_agg( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
struct string_cargo_struct *cls;
OBJ_DATA *obj;
int nobjvnum;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || ch->fighting != NULL)
return FALSE;
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if (victim != ch && IS_NPC(victim) &&
(victim->act & ACT_AGGRESSIVE) == ACT_AGGRESSIVE)
{
if (cls->ncount < 1)
act( "$n screams 'PROTECT THE INNOCENT!! BANZAI!!", ch, NULL, NULL,
TO_ROOM);
else
act( cls->string_list[0], ch, NULL, NULL, TO_ROOM );
multi_hit( ch, victim, TYPE_UNDEFINED );
return TRUE;
}
}
return FALSE;
}
/*
Agg-if-object: Attacks players who have an item in their inventory, say
alcohol or they have stolen some holy relic.
*/
// @@@ Modify this to take a list...
bool spec_agg_if_object( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
struct string_cargo_struct *cls;
OBJ_DATA *obj;
int nobjvnum;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 2 || ch->fighting != NULL)
return FALSE;
nobjvnum = atoi(cls->string_list[0]);
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
/* @@@ This needs to be replaced with a no-hassle check */
if (!IS_IMMORTAL(victim))
{
for ( obj = victim->carrying; obj != NULL; obj = obj->next_content )
{
if ( obj->pIndexData->vnum == nobjvnum )
break;
}
if (obj)
{
act( cls->string_list[1], ch, NULL, NULL, TO_ROOM );
multi_hit( ch, victim, TYPE_UNDEFINED );
return TRUE;
}
}
}
return FALSE;
}
bool spec_circuit( CHAR_DATA *ch )
{
OBJ_DATA *inv;
int nobjvnum;
struct string_cargo_struct *cls;
struct char_cargo_struct *mobcargo = ch->cargo;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
/* If this mob is freshly popped, initialize the character cargo */
if (mobcargo == 0)
{
mobcargo = ch->cargo = calloc(1, sizeof (struct char_cargo_struct));
mobcargo->timer = 0;
mobcargo->state = 0;
}
// Is the mob able to perform it's next action?
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 1 || ch->fighting != NULL)
return FALSE;
// Is it time for a state change?
// @@@ 10 is hardcoded...
if (mobcargo->timer++ >= 10)
{
interpret(ch, cls->string_list[mobcargo->state]);
mobcargo->timer = 0;
if (mobcargo->state < cls->ncount-1)
mobcargo->state++;
else
mobcargo->state = 0;
return TRUE;
}
return FALSE;
}
/* This spec-fun lets mobs act the way they do on some muds--Remebering who
they last fought against and going aggressive against that player.
*/
bool spec_hatred( CHAR_DATA *ch )
{
char *char_enemy = ch->cargo; /* Store current hated char in cargo */
CHAR_DATA *victim, *v_next;
if (!IS_AWAKE(ch)) /* Mob can't hate while asleep */
return FALSE;
if (ch->fighting) /* Is the mobile fighting? */
{
/* If the mobile is fighting a player, check and see if it is a player
the mobile doesn't currently hate. */
if (!IS_NPC(ch->fighting) &&
(!char_enemy ||
str_cmp(ch->fighting->name, char_enemy) == TRUE))
{
free_string( char_enemy );
ch->cargo = str_dup( ch->fighting->name );
}
}
/* The mobile is not fighting. Does the mobile hate anyone? */
else if (char_enemy)
{
/* Check the room for the player the mobile hates: */
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
/* @@@ A no-hassle check is needed here. */
if (!IS_NPC(victim) && str_cmp(victim->name, char_enemy) == FALSE)
{
act( "$n screams with rage!", ch, NULL, NULL, TO_ROOM );
multi_hit( ch, victim, TYPE_UNDEFINED );
return TRUE;
}
}
}
return FALSE;
}
/*
* Psionicist spec_fun by Thelonius for EnvyMud.
*/
bool spec_cast_psionicist( CHAR_DATA *ch )
{
CHAR_DATA *victim;
char *spell;
int sn;
if ( ch->position != POS_FIGHTING )
return FALSE;
for ( victim = ch->in_room->people; victim; victim = victim->next_in_room )
{
if ( victim->fighting == ch && can_see( ch, victim )
&& number_bits( 2 ) == 0 )
break;
}
if ( !victim )
return FALSE;
for ( ; ; )
{
int min_level;
switch ( number_bits( 4 ) )
{
case 0: min_level = 0; spell = "mind thrust"; break;
case 1: min_level = 4; spell = "psychic drain"; break;
case 2: min_level = 6; spell = "agitation"; break;
case 3: min_level = 8; spell = "psychic crush"; break;
case 4: min_level = 9; spell = "project force"; break;
case 5: min_level = 13; spell = "ego whip"; break;
case 6: min_level = 14; spell = "energy drain"; break;
case 7:
case 8: min_level = 17; spell = "psionic blast"; break;
case 9: min_level = 20; spell = "detonate"; break;
case 10: min_level = 27; spell = "disintegrate"; break;
default: min_level = 25; spell = "ultrablast"; break;
}
if ( ch->level >= min_level )
break;
}
if ( ( sn = skill_lookup( spell ) ) < 0 )
return FALSE;
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
return TRUE;
}
#if 0
/* This current version of spec_animated_dead just emotes. It could be
enhanced in all kinds of ways... Tying in HPs with the charm-master,
turning on the charm master, etc. When the charm wears off, the mobile
turns to dust.
*/
bool spec_animated_dead( CHAR_DATA *ch )
{
if ( !IS_AFFECTED(ch, AFF_CHARM) )
{
act( "$n crumbles into dust.", ch, NULL, NULL, TO_ROOM );
stop_fighting( ch, TRUE );
/* Uncomment the following line if you have mobprogs */
/* mprog_death_trigger( ch ); */
extract_char( ch, TRUE );
return TRUE;
}
switch ( number_bits(5) )
{
case 0:
act( "Another gobbet of lose flesh falls off $n.", ch, NULL, NULL, TO_ROOM );
return TRUE;
case 1:
act( "$n lets loose with a blood-curdling wail.", ch, NULL, NULL, TO_ROOM );
return TRUE;
case 2:
act( "$n's odor is getting very bad. You gag.", ch, NULL, NULL, TO_ROOM );
return TRUE;
default:
break;
}
return FALSE;
}
#else
bool spec_animated_dead( CHAR_DATA *ch )
{
act( "$n crumbles into dust.", ch, NULL, NULL, TO_ROOM );
stop_fighting( ch, TRUE );
/* Uncomment the following line if you have mobprogs */
/* mprog_death_trigger( ch ); */
extract_char( ch, TRUE );
return TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -