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.