low4/area/
low4/area/imc/
low4/notes/
void act( const char *format, CHAR_DATA *ch, const void *arg1,
              const void *arg2, int type )
{
    static char * const he_she  [] = { "it",  "he",  "she" };
    static char * const him_her [] = { "it",  "him", "her" };
    static char * const his_her [] = { "its", "his", "her" };
    CHAR_DATA           *to;
    CHAR_DATA           *vch = ( CHAR_DATA * ) arg2;
    CHAR_DATA *to_old;
    CHAR_DATA *familiar = NULL;
    CHAR_DATA *wizard = NULL;
    bool is_fam;

    OBJ_DATA            *obj1 = ( OBJ_DATA  * ) arg1;
    OBJ_DATA            *obj2 = ( OBJ_DATA  * ) arg2;
    const       char    *str;
    char                *i;
    char                *point;
    char                *pbuff;
    char                buf[ MAX_STRING_LENGTH   ];
    char                buffer[ MAX_STRING_LENGTH*2 ];
    char                fname[ MAX_INPUT_LENGTH  ];
    bool                fColour = FALSE;
    bool		is_ok;
    int			min_pos = 5;

    if( !format || !*format )
        return;

    if( !ch || !ch->in_room )
        return;

     to = ch->in_room->people;
     if( type == TO_VICT )
     {
         if( !vch )
         {
             bug( "Act: null vch with TO_VICT.", 0 );
             return;
         }

        if( !vch->in_room )
            return;

         to = vch->in_room->people;
     }

	is_fam = FALSE;
	to_old = to;


     for( ; to ; to = to->next_in_room )
     {
         if( !to->desc || to->position < min_pos )
             continue;

         if( type == TO_CHAR && to != ch )
             continue;
         if( type == TO_VICT && ( to != vch || to == ch ) )
             continue;
         if( type == TO_ROOM && to == ch )
             continue;
         if( type == TO_NOTVICT && ( to == ch || to == vch ) )
             continue;

	if ( to->desc == NULL && IS_NPC(to) && (wizard = to->wizard) != NULL )
	{
	    if (!IS_NPC(wizard) && ((familiar=wizard->pcdata->familiar) != NULL)
		&& familiar == to)
	    {
		if (to->in_room == ch->in_room && 
		    wizard->in_room != to->in_room)
		{
		    to = wizard;
		    is_fam = TRUE;
		}
	    }
	}




	if ( to->desc == NULL || !IS_AWAKE(to) )
	{
	    if (is_fam) to = to_old;
	    continue;
	}

        if (ch->in_room->vnum == ROOM_VNUM_IN_OBJECT)
        {
            is_ok = FALSE;

            if (!IS_NPC(ch) && ch->pcdata->chobj != NULL &&
                ch->pcdata->chobj->in_room != NULL &&
                !IS_NPC(to) && to->pcdata->chobj != NULL &&
                to->pcdata->chobj->in_room != NULL &&
                ch->in_room == to->in_room)
                    is_ok = TRUE; else is_ok = FALSE;

            if (!IS_NPC(ch) && ch->pcdata->chobj != NULL &&
                ch->pcdata->chobj->in_obj != NULL &&
                !IS_NPC(to) && to->pcdata->chobj != NULL &&
                to->pcdata->chobj->in_obj != NULL &&
                ch->pcdata->chobj->in_obj == to->pcdata->chobj->in_obj)
                    is_ok = TRUE; else is_ok = FALSE;

            if (!is_ok)
            {
                if (is_fam) to = to_old;
                continue;
            }
        }

         point   = buf;
         str     = format;
         while( *str )
         {
             if( *str != '$' )
             {
                 *point++ = *str++;
                 continue;
             }

            i = NULL;
            switch( *str )
            {
                case '$':
                    fColour = TRUE;
                    ++str;
                    i = " <@@@> ";
                    if ( !arg2 && *str >= 'A' && *str <= 'Z' )
                    {
                        bug( "Act: missing arg2 for code %d.", *str );
                        i = " <@@@> ";
                    }
                    else
                    {
                        switch ( *str )
                        {
                            default:
                                bug( "Act: bad code %d.", *str );
                                i = " <@@@> ";
                                break;

                            case 't':
                                i = (char *) arg1;
                                break;

                            case 'T':
                                i = (char *) arg2;
                                break;

                            case 'n':
                                i = PERS( ch,  to  );
                                break;

                            case 'N':
                                i = PERS( vch, to  );
                                break;

                            case 'e':
                                i = he_she  [URANGE(0, ch  ->sex, 2)];
                                break;

                            case 'E':
                                i = he_she  [URANGE(0, vch ->sex, 2)];
                                break;

                            case 'm':
                                i = him_her [URANGE(0, ch  ->sex, 2)];
                                break;

                            case 'M':
                                i = him_her [URANGE(0, vch ->sex, 2)];
                                break;

                            case 's':
                                i = his_her [URANGE(0, ch  ->sex, 2)];
                                break;

                            case 'S':
                                i = his_her [URANGE(0, vch ->sex, 2)];
                                break;

                            case 'p':
                                i = can_see_obj( to, obj1 )
                                  ? obj1->short_descr
                                  : "something";
                                break;

                            case 'P':
                                i = can_see_obj( to, obj2 )
                                  ? obj2->short_descr
                                  : "something";
                                break;

                            case 'd':
                                if ( !arg2 || ((char *) arg2)[0] == '\0' )
                                {
                                    i = "door";
                                }
                                else
                                {
                                    one_argument( (char *) arg2, fname );
                                    i = fname;
                                }
                                break;
                        }
                    }
                    break;

                default:
                    fColour = FALSE;
                    *point++ = *str++;
                    break;
            }

             ++str;
            if( i )
            {
                while( ( *point = *i ) != '\0' )
                {
                    ++point;
                    ++i;
                }
            }
         }

        *point++        = '\n';
        *point++        = '\r';

	if (is_fam)
	{
	    if (to->in_room != ch->in_room && familiar != NULL &&
		familiar->in_room == ch->in_room)
		send_to_char("[ ", to);
	    else
	    {
		to = to_old;
		continue;
	    }
	}


        *point          = '\0';
        buf[0]          = UPPER( buf[0] );
        pbuff           = buffer;
        colourconv( pbuff, buf, to );
        if( to->desc )
            write_to_buffer( to->desc, buffer, 0 );
	if (is_fam) to = to_old;

     }

     return;
 }