⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 special.c

📁 MUD服务器程序
💻 C
📖 第 1 页 / 共 4 页
字号:

    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 + -