The following headache will be provided by Gendi.

************************************************************************************************

** special.c **


DECLARE_SPEC_FUN(	spec_clan_patrol	);

DECLARE_SPEC_FUN(	spec_player_patrol	);

if ( !str_cmp( name, "spec_clan_patrol" ) ) return spec_clan_patrol;

if ( !str_cmp( name, "spec_player_patrol" ) ) return spec_player_patrol;

if ( special == spec_clan_patrol      )      return "spec_clan_patrol";

if ( special == spec_player_patrol      )      return "spec_player_patrol";


WARNING if you choose to change this then the guards on the darkhand (and perhaps elswhere will be screwed up) so you need to add to the #specials section of each area file as stated below (current area files are of course compatible with this change.)

in spec_customs_weapons

I would remove this

if (  victim->pcdata && victim->pcdata->clan && !str_cmp(victim->pcdata->clan->mainclan->name , ch->mob_clan )  




bool spec_clan_guard( CHAR_DATA *ch )
{
    CHAR_DATA *victim;
    CHAR_DATA *v_next;

    if ( !IS_AWAKE(ch) || ch->fighting )
	return FALSE;

    if ( !get_clan( ch->mob_clan )
	return FALSE;

    for ( victim = ch->in_room->first_person; victim; victim = v_next )
    {
	v_next = victim->next_in_room;
	if ( !can_see( ch, victim ) )
	   continue;
        if ( get_timer(victim, TIMER_RECENTFIGHT) > 0 )
	   continue;

        if ( !IS_NPC( victim ) && victim->pcdata && victim->pcdata->clan && IS_AWAKE(victim) )
          {
              if ( victim->pcdata->clan->mainclan && get_clan( ch->mob_clan )->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->mainclan->name , victim->pcdata->clan->mainclan->name ) )
                 return FALSE;
              }
              else if ( victim->pcdata->clan->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->name , victim->pcdata->clan->mainclan->name ) )
                 return FALSE;
              }
              else if ( get_clan( ch->mob_clan )->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->mainclan->name , victim->pcdata->clan->name ) )
                 return FALSE;
              }
              else
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->name , victim->pcdata->clan->name ) )
                 return FALSE;
              }    

	      do_yell( ch, "Hey you're not allowed in here!" );
              multi_hit( ch, victim, TYPE_UNDEFINED );
              return TRUE;         
          }
    }

    return FALSE;
}

bool spec_player_guard( CHAR_DATA *ch )
{
    CHAR_DATA *victim;
    CHAR_DATA *v_next;

    if ( !IS_AWAKE(ch) || ch->fighting )
	return FALSE;

    for ( victim = ch->in_room->first_person; victim; victim = v_next )
    {
	v_next = victim->next_in_room;
	if ( !can_see( ch, victim ) )
	   continue;
        if ( get_timer(victim, TIMER_RECENTFIGHT) > 0 )
	   continue;
        if ( !IS_NPC( victim ) && victim->pcdata && IS_AWAKE(victim)
               && str_cmp( ch->leader->name , victim->name ) )
          {
	      do_yell( ch, "Hey you're not allowed in here!" );
              multi_hit( ch, victim, TYPE_UNDEFINED );
              return TRUE;         
          }
    }

    return FALSE;
}

bool spec_clan_patrol( CHAR_DATA *ch )
{
    CHAR_DATA *victim;
    CHAR_DATA *v_next;

    if ( !IS_AWAKE(ch) || ch->fighting )
	return FALSE;

    if ( !get_clan( ch->mob_clan )
	return FALSE;

    for ( victim = ch->in_room->first_person; victim; victim = v_next )
    {
	v_next = victim->next_in_room;
	if ( !can_see( ch, victim ) )
	   continue;
        if ( get_timer(victim, TIMER_RECENTFIGHT) > 0 )
	   continue;
        if ( !IS_NPC( victim ) && victim->pcdata && victim->pcdata->clan && IS_AWAKE(victim)
               && ( victim->top_level > 29 ))
          {
              if ( victim->pcdata->clan->mainclan && get_clan( ch->mob_clan )->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->mainclan->name , victim->pcdata->clan->mainclan->name ) )
                 return FALSE;
              }
              else if ( victim->pcdata->clan->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->name , victim->pcdata->clan->mainclan->name ) )
                 return FALSE;
              }
              else if ( get_clan( ch->mob_clan )->mainclan )
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->mainclan->name , victim->pcdata->clan->name ) )
                 return FALSE;
              }
              else
              {
                 if ( !str_cmp( get_clan( ch->mob_clan )->name , victim->pcdata->clan->name ) )
                 return FALSE;
              }    

          
	      do_yell( ch, "Hey you're not allowed around here!" );
              multi_hit( ch, victim, TYPE_UNDEFINED );
              return TRUE;         
          }
    }

    return FALSE;
}

bool spec_player_patrol( CHAR_DATA *ch )
{
    CHAR_DATA *victim;
    CHAR_DATA *v_next;

    if ( !IS_AWAKE(ch) || ch->fighting )
	return FALSE;

    for ( victim = ch->in_room->first_person; victim; victim = v_next )
    {
	v_next = victim->next_in_room;
	if ( !can_see( ch, victim ) )
	   continue;
        if ( get_timer(victim, TIMER_RECENTFIGHT) > 0 )
	   continue;
        if ( !IS_NPC( victim ) && victim->pcdata && IS_AWAKE(victim)
               && ( victim->top_level > 29 ) && str_cmp( ch->leader->name , victim->name ) )
          {
	      do_yell( ch, "Hey you're not allowed around here!" );
              multi_hit( ch, victim, TYPE_UNDEFINED );
              return TRUE;         
          }
    }

    return FALSE;
}








************************************************************************************************


**mud.h**

add to struct mob_index_data

char		*	mob_clan

This (I think) is needed so I can load and save mob_clan info


change MOB_VNUM_IMP_GUARD to MOB_VNUM_GUARD

Make sure the guard can't move!

change MOB_VNUM_NR_TROOPER to MOB_VNUM_PATROL
keep MOB_VNUM_MERCINARY

(remove the other MOB_VNUMS to save space)


************************************************************************************************


** limbo.are **
alter the  impguard, new rep trooper so that they are generic.
keep MOB_VNUM_MERCINARY

(remove the other MOB_VNUMS to save space)



************************************************************************************************

**swskils.c**

I have included the whole procedures for the ones that I have modified due to the extent of the modifications.


void add_reinforcements( CHAR_DATA *ch )
{
     MOB_INDEX_DATA  * pMobIndex;
     OBJ_DATA        * blaster;
     OBJ_INDEX_DATA  * pObjIndex;
     
     if ( ( pMobIndex = get_mob_index( ch->backup_mob ) ) == NULL )
        return;         

     if ( ch->backup_mob == MOB_VNUM_MERCINARY )
     {
        CHAR_DATA * mob[3];
        int         mob_cnt;
        
        send_to_char( "Your reinforcements have arrived.\n\r", ch );
        for ( mob_cnt = 0 ; mob_cnt < 3 ; mob_cnt++ )
        {
            int ability;
            mob[mob_cnt] = create_mobile( pMobIndex );
            char_to_room( mob[mob_cnt], ch->in_room );
            act( AT_IMMORT, "$N has arrived.", ch, NULL, mob[mob_cnt], TO_ROOM );
            mob[mob_cnt]->top_level = ch->skill_level[LEADERSHIP_ABILITY]/3;
            for ( ability = 0 ; ability < MAX_ABILITY ; ability++ )
                     mob[mob_cnt]->skill_level[ability] = mob[mob_cnt]->top_level;
            mob[mob_cnt]->hit = mob[mob_cnt]->top_level*15;
            mob[mob_cnt]->max_hit = mob[mob_cnt]->hit;
            mob[mob_cnt]->armor = 100- mob[mob_cnt]->top_level*2.5;
            mob[mob_cnt]->damroll = mob[mob_cnt]->top_level/5;
            mob[mob_cnt]->hitroll = mob[mob_cnt]->top_level/5;
            if ( ( pObjIndex = get_obj_index( OBJ_VNUM_BLASTECH_E11 ) ) != NULL )
            {
                 blaster = create_object( pObjIndex, mob[mob_cnt]->top_level );
                 obj_to_char( blaster, mob[mob_cnt] );
                 equip_char( mob[mob_cnt], blaster, WEAR_WIELD );                        
            } 
            if ( mob[mob_cnt]->master )
	       stop_follower( mob[mob_cnt] );
	    add_follower( mob[mob_cnt], ch );
            SET_BIT( mob[mob_cnt]->affected_by, AFF_CHARM );
            do_setblaster( mob[mob_cnt] , "full" );
        }
     }
     else if ( ch->backup_mob == MOB_VNUM_GUARD )
     {
        CHAR_DATA *mob;
        int ability;
        
        mob = create_mobile( pMobIndex );
        char_to_room( mob, ch->in_room );
        if ( ch->pcdata && ch->pcdata->clan )
        {
          char tmpbuf[MAX_STRING_LENGTH];
        
          STRFREE( mob->name );
          mob->name = STRALLOC( "guard" );
          sprintf( tmpbuf , "(%s) Guard\n" , ch->pcdata->clan->name );
          STRFREE( mob->long_descr );
          mob->long_descr = STRALLOC( tmpbuf );
          mob->mob_clan = ch->pcdata->clan->name;
          mob->spec_fun = spec_lookup("spec_clan_guard"); 
        }
        else
        {
          char tmpbuf[MAX_STRING_LENGTH];
        
          STRFREE( mob->name );
          mob->name = STRALLOC( "guard");
          sprintf( tmpbuf , "%s's guard\n" , ch->name );
          STRFREE( mob->long_descr );
          mob->long_descr = STRALLOC( tmpbuf );
         /* use leader because its handy for spec_player_guard*/
          mob->leader = ch;
          mob->spec_fun = spec_lookup("spec_player_guard");
        }
         
        act( AT_IMMORT, "$N has arrived.", ch, NULL, mob, TO_ROOM );
        send_to_char( "Your guard has arrived.\n\r", ch );
        mob->top_level = ch->skill_level[LEADERSHIP_ABILITY];
        for ( ability = 0 ; ability < MAX_ABILITY ; ability++ )
            mob->skill_level[ability] = mob->top_level;
        mob->hit = mob->top_level*15;
        mob->max_hit = mob->hit;
        mob->armor = 100- mob->top_level*2.5;
        mob->damroll = mob->top_level/5;
        mob->hitroll = mob->top_level/5;
        if ( ( pObjIndex = get_obj_index( OBJ_VNUM_BLASTECH_E11 ) ) != NULL )
        {
            blaster = create_object( pObjIndex, mob->top_level );
            obj_to_char( blaster, mob );
            equip_char( mob, blaster, WEAR_WIELD );
            do_setblaster( mob , "full" );                        
        }
        
      
     }                    
     else
     {
        CHAR_DATA *mob;
        int ability;
        
        mob = create_mobile( pMobIndex );
        char_to_room( mob, ch->in_room );
        if ( ch->pcdata && ch->pcdata->clan )
        {
          char tmpbuf[MAX_STRING_LENGTH];
        
          STRFREE( mob->name );
          mob->name = STRALLOC( "patrol" );
          sprintf( tmpbuf , "(%s) Patrol\n" , ch->pcdata->clan->name );
          STRFREE( mob->long_descr );
          mob->long_descr = STRALLOC( tmpbuf );
          mob->mob_clan = ch->pcdata->clan->name; 
          mob->spec_fun = spec_lookup("spec_clan_patrol"); 
        }
        else
        {
          char tmpbuf[MAX_STRING_LENGTH];
        
          STRFREE( mob->name );
          mob->name = STRALLOC( "patrol" );
          sprintf( tmpbuf , "%s's Patrol\n" , ch->name );
          STRFREE( mob->long_descr );
          mob->long_descr = STRALLOC( tmpbuf );
         /* use leader because its handy for spec_player_guard*/
          mob->leader = ch;
          mob->spec_fun = spec_lookup("spec_player_patrol"); 
        }
         
        act( AT_IMMORT, "$N has arrived.", ch, NULL, mob, TO_ROOM );
        send_to_char( "Your patrol has arrived.\n\r", ch );
        mob->top_level = ch->skill_level[LEADERSHIP_ABILITY];
        for ( ability = 0 ; ability < MAX_ABILITY ; ability++ )
            mob->skill_level[ability] = mob->top_level;
        mob->hit = mob->top_level*10;
        mob->max_hit = mob->hit;
        mob->armor = 100- mob->top_level*1.5;
        mob->damroll = mob->top_level/3;
        mob->hitroll = mob->top_level/3;
        if ( ( pObjIndex = get_obj_index( OBJ_VNUM_BLASTECH_E11 ) ) != NULL )
        {
            blaster = create_object( pObjIndex, mob->top_level );
            obj_to_char( blaster, mob );
            equip_char( mob, blaster, WEAR_WIELD );  
            do_setblaster( mob , "full" );                       
        }
        
       
     } 

}





void do_postguard( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    int chance, credits;
    
    if ( IS_NPC( ch ) || !ch->pcdata )
    	return;
    	
    strcpy( arg, argument );    
    
    switch( ch->substate )
    { 
    	default:
    	        if ( ch->backup_wait )
    	        {
    	            send_to_char( "&RYou already have backup coming.\n\r", ch );
    	            return;
    	        }
    	        /* removed as players can now have guards.
    	        if ( !ch->pcdata->clan )
    	        {
    	            send_to_char( "&RYou need to be a member of an organization before you can call for a guard.\n\r", ch );
    	            return;
    	        }    
    	        */
    	        if ( ch->gold < ch->skill_level[LEADERSHIP_ABILITY] * 30 )
    	        {
    	            ch_printf( ch, "&RYou dont have enough credits.\n\r", ch );
    	            return;
    	        }    
    	        
    	        chance = (int) (ch->pcdata->learned[gsn_postguard]);
                if ( number_percent( ) < chance )
    		{
    		   send_to_char( "&GYou begin making the call for reinforcements.\n\r", ch);
    		   act( AT_PLAIN, "$n begins issuing orders int $s comlink.", ch,
		        NULL, argument , TO_ROOM );
		   add_timer ( ch , TIMER_DO_FUN , 1 , do_postguard , 1 );
    		   ch->dest_buf = str_dup(arg);
    		   return;
	        }
	        send_to_char("&RYou call for a guard but nobody answers.\n\r",ch);
	        learn_from_failure( ch, gsn_postguard );
    	   	return;	
    	
    	case 1:
    		if ( !ch->dest_buf )
    		   return;
    		strcpy(arg, ch->dest_buf);
    		DISPOSE( ch->dest_buf);
    		break;
    		
    	case SUB_TIMER_DO_ABORT:
    		DISPOSE( ch->dest_buf );
    		ch->substate = SUB_NONE;    		                                   
    	        send_to_char("&RYou are interupted before you can finish your call.\n\r", ch);
    	        return;
    }
    
    ch->substate = SUB_NONE;
    
    send_to_char( "&GYour guard is on the way.\n\r", ch);
    
    credits = ch->skill_level[LEADERSHIP_ABILITY] * 30;
    ch_printf( ch, "It cost you %d credits.\n\r", credits);
    ch->gold -= UMIN( credits , ch->gold );

    learn_from_success( ch, gsn_postguard );


/* no longer use this
    
    if ( nifty_is_name( "empire" , ch->pcdata->clan->name ) )
       ch->backup_mob = MOB_VNUM_IMP_GUARD;
    else if ( nifty_is_name( "republic" , ch->pcdata->clan->name ) )
       ch->backup_mob = MOB_VNUM_NR_GUARD;
    else
       ch->backup_mob = MOB_VNUM_BOUNCER;

*/

   
    ch->backup_mob = MOB_VNUM_GUARD;
      

    ch->backup_wait = 1;

}


void do_add_patrol( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    int chance, credits;
    
    if ( IS_NPC( ch ) || !ch->pcdata )
    	return;
    	
    strcpy( arg, argument );    
    
    switch( ch->substate )
    { 
    	default:
    	        if ( ch->backup_wait )
    	        {
    	            send_to_char( "&RYou already have backup coming.\n\r", ch );
    	            return;
    	       
    	        if ( ch->gold < ch->skill_level[LEADERSHIP_ABILITY] * 17 )
    	        {
    	            ch_printf( ch, "&RYou dont have enough credits.\n\r", ch );
    	            return;
    	        }    
    	        
    	        chance = (int) (ch->pcdata->learned[gsn_addpatrol]);
                if ( number_percent( ) < chance )
    		{
    		   send_to_char( "&GYou begin making the call for reinforcements.\n\r", ch);
    		   act( AT_PLAIN, "$n begins issuing orders int $s comlink.", ch,
		        NULL, argument , TO_ROOM );
		   add_timer ( ch , TIMER_DO_FUN , 1 , do_add_patrol , 1 );
    		   ch->dest_buf = str_dup(arg);
    		   return;
	        }
	        send_to_char("&RYou call for a patrol but nobody answers.\n\r",ch);
	        learn_from_failure( ch, gsn_addpatrol );
    	   	return;	
    	
    	case 1:
    		if ( !ch->dest_buf )
    		   return;
    		strcpy(arg, ch->dest_buf);
    		DISPOSE( ch->dest_buf);
    		break;
    		
    	case SUB_TIMER_DO_ABORT:
    		DISPOSE( ch->dest_buf );
    		ch->substate = SUB_NONE;    		                                   
    	        send_to_char("&RYou are interupted before you can finish your call.\n\r", ch);
    	        return;
    }
    
    ch->substate = SUB_NONE;
    
    send_to_char( "&GYour patrol is on the way.\n\r", ch);
    
    credits = ch->skill_level[LEADERSHIP_ABILITY] * 17;
    ch_printf( ch, "It cost you %d credits.\n\r", credits);
    ch->gold -= UMIN( credits , ch->gold );

    learn_from_success( ch, gsn_addpatrol );

   
    ch->backup_mob = MOB_VNUM_PATROL;
       
     
    ch->backup_wait = 1;

}




void do_reinforcements( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    int chance, credits;
    
    if ( IS_NPC( ch ) || !ch->pcdata )
    	return;
    	
    strcpy( arg, argument );    
    
    switch( ch->substate )
    { 
    	default:
    	        if ( ch->backup_wait )
    	        {
    	            send_to_char( "&RYour reinforcements are already on the way.\n\r", ch );
    	            return;
    	        }
    	        /* players can now do this
    	        if ( !ch->pcdata->clan )
    	        {
    	            send_to_char( "&RYou need to be a member of an organization before you can call for reinforcements.\n\r", ch );
    	            return;
    	        }    
    	        
                */
    	        if ( ch->gold < ch->skill_level[LEADERSHIP_ABILITY] * 50 )
    	        {
    	            ch_printf( ch, "&RYou dont have enough credits to send for reinforcements.\n\r" );
    	            return;
    	        }    
    	        
    	        chance = (int) (ch->pcdata->learned[gsn_reinforcements]);
                if ( number_percent( ) < chance )
    		{
    		   send_to_char( "&GYou begin making the call for reinforcements.\n\r", ch);
    		   act( AT_PLAIN, "$n begins issuing orders int $s comlink.", ch,
		        NULL, argument , TO_ROOM );
		   add_timer ( ch , TIMER_DO_FUN , 1 , do_reinforcements , 1 );
    		   ch->dest_buf = str_dup(arg);
    		   return;
	        }
	        send_to_char("&RYou call for reinforcements but nobody answers.\n\r",ch);
	        learn_from_failure( ch, gsn_reinforcements );
    	   	return;	
    	
    	case 1:
    		if ( !ch->dest_buf )
    		   return;
    		strcpy(arg, ch->dest_buf);
    		DISPOSE( ch->dest_buf);
    		break;
    		
    	case SUB_TIMER_DO_ABORT:
    		DISPOSE( ch->dest_buf );
    		ch->substate = SUB_NONE;    		                                   
    	        send_to_char("&RYou are interupted before you can finish your call.\n\r", ch);
    	        return;
    }
    
    ch->substate = SUB_NONE;
    
    send_to_char( "&GYour reinforcements are on the way.\n\r", ch);
    credits = ch->skill_level[LEADERSHIP_ABILITY] * 50;
    ch_printf( ch, "It cost you %d credits.\n\r", credits);
    ch->gold -= UMIN( credits , ch->gold );
             
    learn_from_success( ch, gsn_reinforcements );
 

/* removed   
    if ( nifty_is_name( "empire" , ch->pcdata->clan->name ) )
       ch->backup_mob = MOB_VNUM_STORMTROOPER;
    else if ( nifty_is_name( "republic" , ch->pcdata->clan->name ) )
       ch->backup_mob = MOB_VNUM_NR_TROOPER;
    else
       ch->backup_mob = MOB_VNUM_MERCINARY;
*/

/* This really is a player only thing so only mercs can be hired. */
   
     ch->backup_mob = MOB_VNUM_MERCINARY;
    

     ch->backup_wait = number_range(1,2);
    
}


god the changes just keep coming, when I started a couple of skills I thought it would only be a few things
but I keep getting ideas!!!



************************************************************************************************



** db.c **

replace 
mob->mob_clan        = STRALLOC("");

with
if ( pIndexMob->mob_clan )
mob->mob_clan        = pIndexMob->mob_clan;
else
mob->mob_clan        = STRALLOC("");


in load_specials

	case 'C':
	    pMobIndex		= get_mob_index	( fread_number ( fp ) );
	    pMobIndex->mob_clan = STRALLOC( fread_string ( fp ) );
	   
	    break;

This is so mob_clan can be set in area file.



************************************************************************************************



** build.c **

in area_fold

if ( pMobIndex->mob_clan )
	fprintf( fpout, "C  %d %s~\n",	pMobIndex->vnum, pMobIndex->mob_clan );
	
put this straight after the special save for M, within the for loop.

Now mob_clan can be saved too.


in do_mset

in the part for setting clans, change


	if ( IS_NPC(victim) )
	{
	    send_to_char( "Not on NPC's.\n\r", ch );
	    return;
	}

	
to

	if ( IS_NPC(victim) )
	{
		if ( !arg3 || arg3[0] == '\0' )
		{
			STRFREE( victim->mob_clan );
			victim->mob_clan	= STRALLOC( "" );
			send_to_char( "Clan unset.\n\r", ch );
			return;
		}

	clan = get_clan( arg3 );
	if ( !clan )
	{
		send_to_char( "No such clan.\n\r", ch );
		return;
	}
	STRFREE( victim->mob_clan );
	victim->mob_clan = QUICKLINK( clan->name );
	send_to_char( "Clan set.\n\r", ch );

	return;
	}





************************************************************************************************


** act_wiz **

in do_mstat

change the line 

	ch_printf( ch, "Name: %s     Organization: %s\n\r",
	victim->name,
	( IS_NPC( victim ) || !victim->pcdata->clan ) ? "(none)" 
			       : victim->pcdata->clan->name );

to 

if ( IS_NPC( victim )
{
	ch_printf( ch, "Name: %s     Organization: %s\n\r",
	victim->name,
	( !get_clan( victim->mob_clan ) ) ? "(none)" 
	: get_clan( victim->mob_clan )->name );
}
else
{
	ch_printf( ch, "Name: %s     Organization: %s\n\r",
	victim->name,
	( !victim->pcdata->clan ) ? "(none)" 
	: victim->pcdata->clan->name );
}



mob clans can be set in area files by using C <MOBVNUM> <CLANNAME>~ in the #SPECIALS section.


As you might have also noticed clan guards now don't attack players in their clan or subclans, this had bugged me.

Initial I did think about making mob_clan into a CLAN_DATA type, but it seems easier for the moment to leave it at a char, change it if you like, but there is not much point( unless you don't like accessing the clan data using get_clan!)

Okay okay, no more changes, for now.

Plz send me comments/improvements, I'm NOT a good C coder, what I've done probably sucks, but I can't tell!


I hope you don't have problems with this, it is what I have done, and mine works, but if I've missed out any changes that are needed feel free to question me.

Gendi.
mailto:bleac@btinternet.com

Please feel free to pass this on, but please keep my name and address in here.