This function allows "watchers" in a room to be drawn into a fight.  For
instance, 5 people are in a room.  2 fight.  One (or more) of the
remaining 3 people/mobs _may_ be drawn in against one of the fighters due
to "being bumped" or whatever.

Use this code at your own risk.  I make no guarantees about anything. :)
Also, it should be used according to the diku/merc/ROM copywrite licenses.
If you use it, I would appreciate appropriate credit within the code.
Also, please email me to let me know that you're using it at the following
address: amaslin@hotmail.com.  Thanks!

Any questions, comments, suggestions, or bug reports (please sent NICELY)
should also be sent to that address.

Thale (amaslin@hotmail.com)

------------

This was written for a PK mud, so there's a 7 level limit to attacking
other players.  IS_PEACEKEEPER is a macro defined in merc.h.  It's a
non-PK (protected) clan, so they can't be attacked by players.  If some of
the random number calls seem weird, I made them like that for possible
future changes to allow different results depending on the random number
generated - and I just like to be different. :)  The reason I have 45
slots defined for people is because I want mobs to be 3 times as likely as
players to be attacked, as well as limiting memory used.  If you don't
have a PK mud, you'll want to modify that section, and could probably just
drop the total to 15 instead of 45.


** in fight.c

In the local functions, define crowd_brawl as follows:

void    crowd_brawl     args( ( CHAR_DATA *ch ) );


Now, find this section:
	if ( IS_AWAKE(ch) && ch->in_room == victim->in_room )
	    multi_hit( ch, victim, TYPE_UNDEFINED );
	else
	    stop_fighting( ch, FALSE );

and replace it with this:

	if ( IS_AWAKE(ch) && ch->in_room == victim->in_room )
	{
	    /* calls from here, because everyone actively fighting
	     * (as in, not asleep and in the room, see "if" check above)
	     * could pull a person into the fight, either against them
	     * or against the oponent.  Also called before a person hits
	     * so that no one gets drawn in after a fight ends due to death.
	     */
	    crowd_brawl(ch);

	    multi_hit( ch, victim, TYPE_UNDEFINED );
	}
	else
	    stop_fighting( ch, FALSE );


Now somewhere in the code add this function:

/* For watchers in room to be drawn into fights.
 * Original idea taken from SneezyMUD.
 * Coded by Thale.
 */
void crowd_brawl(CHAR_DATA *ch)
{
    CHAR_DATA *rch, *rch_next, *vch, *vch_next;
    CHAR_DATA *is_fighting[45];
    SHOP_DATA *pshop;
    int chance;
    int counter;
    int to_fight;

    for (rch = ch->in_room->people; rch != NULL; rch = rch_next)
    {
	rch_next = rch->next_in_room;

	chance=number_range(1,300);

	if ((rch->fighting == NULL)
	 &&((!IS_IMMORTAL(rch) && !IS_NPC(rch))
	 ||(IS_NPC(rch)
	 &&!(IS_SET(rch->act,ACT_TRAIN)
	 ||  IS_SET(rch->act,ACT_PRACTICE)
	 ||  IS_SET(rch->act,ACT_IS_HEALER)
	 ||  IS_SET(rch->act,ACT_IS_CHANGER)
	 ||  IS_SET(rch->act,ACT_BOUNTY_MAKER)
	 || ((pshop = rch->pIndexData->pShop) != NULL))))
	 &&IS_AWAKE(rch)
	 &&(chance <= 2))
	{
	  counter = 0;
	  for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
	  {
	    vch_next = vch->next_in_room;
	    if ((vch->fighting != NULL) && (counter <= 44))
	    {
	      is_fighting[counter] = vch;
	      ++counter;
	      /* if it's an NPC, thrice as likely as a PC to be attacked */
	      /* max of 45 fighting PC/NPCs in array, can't exceed */
	      if ((IS_NPC(vch)) && (counter <= 44))
	      {
	        is_fighting[counter] = vch;
	        ++counter;
	      }
	      if ((IS_NPC(vch)) && (counter <= 44))
	      {
	        is_fighting[counter] = vch;
	        ++counter;
	      }
  	    }
	  }
	  /* random number of mob in array to fight */
	  to_fight = number_range(1,counter);
	  /* (to_fight -1) because arrays start at 0 not at 1 */
	  to_fight -= 1;

	  /* checks needed for PCs only */
	  if (!IS_NPC(rch) && !IS_NPC(is_fighting[to_fight]))
	  {
	    /* if a Harper, won't attack another PC, and vice versa */
	    if (IS_PEACEKEEPER(rch) || IS_PEACEKEEPER(is_fighting[to_fight]))
	      continue;
	    /* won't attack someone of same clan */
	    if (is_same_clan(rch,is_fighting[to_fight]))
	      continue;

	    /* PK range of 7 level difference in effect between PCs,
	     * and no PC can be drawn in against a victim PC lower
	     * than level 10 (also pursuant to PK rules)
	     */
	    if (((UMAX(rch->level,is_fighting[to_fight]->level) -
		  UMIN(rch->level,is_fighting[to_fight]->level)) > 7)
	       ||(is_fighting[to_fight]->level < 10))
	      continue;
	  }
	  else if (IS_NPC(rch))
	  {
	    /* hack so adept in mud school at diploma beast won't attack
	     * anyone - learned the hard way, oops. :)
	     */
	    if (rch->pIndexData->vnum == 3708)
	      continue;
	  }

	  /* if an immortal is fighting, nothing attacks him/her */
	  if (IS_IMMORTAL(is_fighting[to_fight]))
	    continue;

	  /* resting mobs/players have a smaller chance of being drawn in */
	  if ((rch->position <= POS_RESTING) && (chance > 1))
	    continue;

	  /* gotta see them to attack them */
	  if (!can_see(rch,is_fighting[to_fight]))
	    continue;

	  /* not against group members */
	  if (is_same_group(rch,is_fighting[to_fight]))
	    continue;

	  /* charmed mobs and pets, whether grouped or not */
	  if (IS_AFFECTED(rch,AFF_CHARM)
	   &&((rch->master == is_fighting[to_fight])
	   ||(is_fighting[to_fight]->master == rch)
	   ||(is_fighting[to_fight]->master == rch->master)))
	    continue;

	  if (IS_SET(rch->act,ACT_PET)
	   &&((rch->master == is_fighting[to_fight])
	   ||(is_fighting[to_fight]->master == rch)
	   ||(is_fighting[to_fight]->master == rch->master)))
	    continue;

	  if (is_fighting[to_fight] != NULL)
	  {
	    rch->fighting = is_fighting[to_fight];
	    rch->position = POS_FIGHTING;
	    act("You find yourself caught up in the brawl!",rch,NULL,NULL,TO_CHAR);
	    act("$n finds $mself involved in the brawl.",rch,NULL,NULL,TO_ROOM);
	  }
	  else
	    bug("Crowd_brawl - person to fight is NULL.", 0);
	}
    }
    return;
}  /* end of crowd_brawl */