Bug: Numerous problems with the switch command
Danger: Varies, but usually High to Critical due to crash potential.
Found by: Valcados
Fixed by: Valcados
---
act_wiz.c, do_balzhur
Locate:
set_char_color( AT_WHITE, ch );
send_to_char( "You summon the demon Balzhur to wreak your wrath!\r\n", ch );
send_to_char( "Balzhur sneers at you evilly, then vanishes in a puff of smoke.\r\n", ch );
set_char_color( AT_IMMORT, victim );
send_to_char( "You hear an ungodly sound in the distance that makes your blood run cold!\r\n", victim );
snprintf( buf, MAX_STRING_LENGTH, "Balzhur screams, 'You are MINE %s!!!'", victim->name );
echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL );
victim->level = 2;
victim->trust = 0;
Change to:
victim->level = 2;
victim->trust = 0;
check_switch( victim, TRUE );
set_char_color( AT_WHITE, ch );
send_to_char( "You summon the demon Balzhur to wreak your wrath!\r\n", ch );
send_to_char( "Balzhur sneers at you evilly, then vanishes in a puff of smoke.\r\n", ch );
set_char_color( AT_IMMORT, victim );
send_to_char( "You hear an ungodly sound in the distance that makes your blood run cold!\r\n", victim );
snprintf( buf, MAX_STRING_LENGTH, "Balzhur screams, 'You are MINE %s!!!'", victim->name );
echo_to_all( AT_IMMORT, buf, ECHOTAR_ALL );
act_wiz.c, do_advance
Locate:
if( level < victim->level )
{
ch_printf( ch, "Demoting %s from level %d to level %d!\r\n", victim->name, victim->level, level );
send_to_char( "Cursed and forsaken! The gods have lowered your level...\r\n", victim );
}
Change to:
if( level < victim->level )
{
int tmp = victim->level;
victim->level = level;
check_switch( victim, FALSE );
victim->level = tmp;
ch_printf( ch, "Demoting %s from level %d to level %d!\r\n", victim->name, victim->level, level );
send_to_char( "Cursed and forsaken! The gods have lowered your level...\r\n", victim );
}
act_wiz.c, do_freeze
Locate:
if( get_trust( victim ) >= get_trust( ch ) )
{
send_to_char( "You failed, and they saw...\r\n", ch );
ch_printf( victim, "%s is attempting to freeze you.\r\n", ch->name );
return;
}
if( xIS_SET( victim->act, PLR_FREEZE ) )
{
xREMOVE_BIT( victim->act, PLR_FREEZE );
send_to_char( "Your frozen form suddenly thaws.\r\n", victim );
ch_printf( ch, "%s is now unfrozen.\r\n", victim->name );
}
else
{
xSET_BIT( victim->act, PLR_FREEZE );
send_to_char( "A godly force turns your body to ice!\r\n", victim );
ch_printf( ch, "You have frozen %s.\r\n", victim->name );
}
Change to:
if( get_trust( victim ) >= get_trust( ch ) )
{
send_to_char( "You failed, and they saw...\r\n", ch );
ch_printf( victim, "%s is attempting to freeze you.\r\n", ch->name );
return;
}
if ( victim->desc && victim->desc->original && get_trust(victim->desc->original) >= get_trust(ch) )
{
send_to_char( "For some inexplicable reason, you failed.\r\n", ch );
return;
}
if( xIS_SET( victim->act, PLR_FREEZE ) )
{
xREMOVE_BIT( victim->act, PLR_FREEZE );
send_to_char( "Your frozen form suddenly thaws.\r\n", victim );
ch_printf( ch, "%s is now unfrozen.\r\n", victim->name );
}
else
{
if ( victim->switched )
{
do_return( victim->switched, "" );
set_char_color( AT_LBLUE, victim );
}
xSET_BIT( victim->act, PLR_FREEZE );
send_to_char( "A godly force turns your body to ice!\r\n", victim );
ch_printf( ch, "You have frozen %s.\r\n", victim->name );
}
act_wiz.c, do_bestow
Locate:
ch_printf( victim, "%s has removed your bestowed commands.\r\n", ch->name );
Below that, add:
check_switch( victim, FALSE );
act_wiz.c, do_cedit
Locate:
if( !str_cmp( arg2, "level" ) )
{
int level = atoi( argument );
if( ( level < 0 || level > get_trust( ch ) ) )
{
send_to_char( "Level out of range.\r\n", ch );
return;
}
command->level = level;
send_to_char( "Done.\r\n", ch );
return;
}
Change to:
if( !str_cmp( arg2, "level" ) )
{
int level = atoi( argument );
if( ( level < 0 || level > get_trust( ch ) ) )
{
send_to_char( "Level out of range.\r\n", ch );
return;
}
if ( level > command->level && command->do_fun == do_switch )
{
command->level = level;
check_switches(FALSE);
}
else
command->level = level;
send_to_char( "Done.\r\n", ch );
return;
}
clans.c, do_council_outcast
Locate:
act( AT_MAGIC, "You outcast $N from $t", ch, council->name, victim, TO_CHAR );
Above it, add:
check_switch( ch, FALSE );
build.c, do_mset
Locate:
send_to_char( "Removed from council.\r\n", ch );
Above it, add:
check_switch( victim, FALSE );
handler.c, extract_char
Locate:
if( ch->desc && ch->desc->original )
do_return( ch, "" );
Below it, add:
if( ch->switched && ch->switched->desc )
do_return( ch->switched, "" );
At the end of handler.c, add the following new functions:
void check_switches( bool possess )
{
CHAR_DATA *ch;
for( ch = first_char; ch; ch = ch->next )
check_switch( ch, possess );
}
void check_switch( CHAR_DATA *ch, bool possess )
{
AFFECT_DATA *paf;
CMDTYPE *cmd;
int hash, trust = get_trust(ch);
if( !ch->switched )
return;
if( !possess )
{
for( paf = ch->switched->first_affect; paf; paf = paf->next )
{
if( paf->duration == -1 )
continue;
if( paf->type != -1 && skill_table[paf->type]->spell_fun == spell_possess )
return;
}
}
for( hash = 0; hash < 126; hash++ )
{
for( cmd = command_hash[hash]; cmd; cmd = cmd->next )
{
if( cmd->do_fun != do_switch )
continue;
if( cmd->level <= trust )
return;
if( !IS_NPC(ch) && ch->pcdata->bestowments && is_name( cmd->name, ch->pcdata->bestowments )
&& cmd->level <= trust + sysdata.bestow_dif )
return;
}
}
if( !possess )
{
set_char_color( AT_BLUE, ch->switched );
send_to_char( "You suddenly forfeit the power to switch!\n\r", ch->switched );
}
do_return( ch->switched, "" );
}
mud.h
Locate:
OD *get_objtype args( ( CHAR_DATA * ch, short type ) );
Below it, add:
void check_switches( bool possess );
void check_switch( CHAR_DATA *ch, bool possess );
The switch command can be a very useful tool for imms who like to roleplay with the players, or just surprise them once in awhile with a mob that's more intelligent than usual. The problem with this is that there are a lot of game functions which don't even consider that the imm's body which is hanging around shouldn't be messed with.
This list of fixes is most likely not the end of this either. There are likely to be other bugs found with switch.