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 ~ 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.