📄 special.c
字号:
switch ( number_bits( 4 ) )
{
case 0: min_level = 0; spell = "curse"; break;
case 1: min_level = 3; spell = "weaken"; break;
case 2: min_level = 6; spell = "chill touch"; break;
case 3: min_level = 9; spell = "blindness"; break;
case 4: min_level = 12; spell = "poison"; break;
case 5: min_level = 15; spell = "energy drain"; break;
case 6: min_level = 18; spell = "harm"; break;
case 7: min_level = 21; spell = "teleport"; break;
default: min_level = 24; spell = "gate"; break;
}
if ( ch->level >= min_level )
break;
}
if ( ( sn = skill_lookup( spell ) ) < 0 )
return FALSE;
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
return TRUE;
}
bool spec_executioner( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
char *crime;
if ( !IS_AWAKE(ch) || ch->fighting != NULL )
return FALSE;
crime = "";
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_KILLER) )
{ crime = "KILLER"; break; }
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_THIEF) )
{ crime = "THIEF"; break; }
}
if ( victim == NULL )
return FALSE;
sprintf( buf, "%s is a %s! PROTECT THE INNOCENT! MORE BLOOOOD!!!",
victim->name, crime );
do_shout( ch, buf );
multi_hit( ch, victim, TYPE_UNDEFINED );
char_to_room( create_mobile( get_mob_index(MOB_VNUM_CITYGUARD) ),
ch->in_room );
char_to_room( create_mobile( get_mob_index(MOB_VNUM_CITYGUARD) ),
ch->in_room );
return TRUE;
}
bool spec_fido( CHAR_DATA *ch )
{
OBJ_DATA *corpse;
OBJ_DATA *c_next;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( !IS_AWAKE(ch) )
return FALSE;
for ( corpse = ch->in_room->contents; corpse != NULL; corpse = c_next )
{
c_next = corpse->next_content;
if ( corpse->item_type != ITEM_CORPSE_NPC )
continue;
act( "$n savagely devours a corpse.", ch, NULL, NULL, TO_ROOM );
for ( obj = corpse->contains; obj; obj = obj_next )
{
obj_next = obj->next_content;
obj_from_obj( obj );
obj_to_room( obj, ch->in_room );
}
extract_obj( corpse );
return TRUE;
}
return FALSE;
}
bool spec_guard( CHAR_DATA *ch )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *victim;
CHAR_DATA *v_next;
CHAR_DATA *ech;
char *crime;
int max_evil;
if ( !IS_AWAKE(ch) || ch->fighting != NULL )
return FALSE;
max_evil = 300;
ech = NULL;
crime = "";
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_KILLER) )
{ crime = "KILLER"; break; }
if ( !IS_NPC(victim) && IS_SET(victim->act, PLR_THIEF) )
{ crime = "THIEF"; break; }
if ( victim->fighting != NULL
&& victim->fighting != ch
&& victim->alignment < max_evil )
{
max_evil = victim->alignment;
ech = victim;
}
}
if ( victim != NULL )
{
sprintf( buf, "%s is a %s! PROTECT THE INNOCENT!! BANZAI!!",
victim->name, crime );
do_shout( ch, buf );
multi_hit( ch, victim, TYPE_UNDEFINED );
return TRUE;
}
if ( ech != NULL )
{
act( "$n screams 'PROTECT THE INNOCENT!! BANZAI!!",
ch, NULL, NULL, TO_ROOM );
multi_hit( ch, ech, TYPE_UNDEFINED );
return TRUE;
}
return FALSE;
}
bool spec_janitor( CHAR_DATA *ch )
{
OBJ_DATA *trash;
OBJ_DATA *trash_next;
if ( !IS_AWAKE(ch) )
return FALSE;
for ( trash = ch->in_room->contents; trash != NULL; trash = trash_next )
{
trash_next = trash->next_content;
if ( !IS_SET( trash->wear_flags, ITEM_TAKE ) )
continue;
if ( trash->item_type == ITEM_DRINK_CON
|| trash->item_type == ITEM_TRASH
|| trash->cost < 10 )
{
act( "$n picks up some trash.", ch, NULL, NULL, TO_ROOM );
obj_from_room( trash );
obj_to_char( trash, ch );
return TRUE;
}
}
return FALSE;
}
bool spec_mayor( CHAR_DATA *ch )
{
static const char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
static const char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
static const char *path;
static int pos;
static bool move;
if ( !move )
{
if ( time_info.hour == 6 )
{
path = open_path;
move = TRUE;
pos = 0;
}
if ( time_info.hour == 20 )
{
path = close_path;
move = TRUE;
pos = 0;
}
}
if ( ch->fighting != NULL )
return spec_cast_cleric( ch );
if ( !move || ch->position < POS_SLEEPING )
return FALSE;
switch ( path[pos] )
{
case '0':
case '1':
case '2':
case '3':
move_char( ch, path[pos] - '0' );
break;
case 'W':
ch->position = POS_STANDING;
act( "$n awakens and groans loudly.", ch, NULL, NULL, TO_ROOM );
break;
case 'S':
ch->position = POS_SLEEPING;
act( "$n lies down and falls asleep.", ch, NULL, NULL, TO_ROOM );
break;
case 'a':
act( "$n says 'Hello Honey!'", ch, NULL, NULL, TO_ROOM );
break;
case 'b':
act( "$n says 'What a view! I must do something about that dump!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'c':
act( "$n says 'Vandals! Youngsters have no respect for anything!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'd':
act( "$n says 'Good day, citizens!'", ch, NULL, NULL, TO_ROOM );
break;
case 'e':
act( "$n says 'I hereby declare the city of Midgaard open!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'E':
act( "$n says 'I hereby declare the city of Midgaard closed!'",
ch, NULL, NULL, TO_ROOM );
break;
case 'O':
do_unlock( ch, "gate" );
do_open( ch, "gate" );
break;
case 'C':
do_close( ch, "gate" );
do_lock( ch, "gate" );
break;
case '.' :
move = FALSE;
break;
}
pos++;
return FALSE;
}
bool spec_poison( CHAR_DATA *ch )
{
CHAR_DATA *victim;
if ( ch->position != POS_FIGHTING
|| ( victim = ch->fighting ) == NULL
|| number_percent( ) > 2 * ch->level )
return FALSE;
act( "You bite $N!", ch, NULL, victim, TO_CHAR );
act( "$n bites $N!", ch, NULL, victim, TO_NOTVICT );
act( "$n bites you!", ch, NULL, victim, TO_VICT );
spell_poison( gsn_poison, ch->level, ch, victim );
return TRUE;
}
bool spec_thief( CHAR_DATA *ch )
{
CHAR_DATA *victim;
CHAR_DATA *v_next;
int gold;
if ( ch->position != POS_STANDING )
return FALSE;
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if ( IS_NPC(victim)
|| victim->level >= LEVEL_IMMORTAL
|| number_bits( 2 ) != 0
|| !can_see( ch, victim ) ) /* Thx Glop */
continue;
if ( IS_AWAKE(victim) && number_range( 0, ch->level ) == 0 )
{
act( "You discover $n's hands in your wallet!",
ch, NULL, victim, TO_VICT );
act( "$N discovers $n's hands in $S wallet!",
ch, NULL, victim, TO_NOTVICT );
return TRUE;
}
else
{
gold = victim->gold * number_range( 1, 20 ) / 100;
ch->gold += 7 * gold / 8;
victim->gold -= gold;
return TRUE;
}
}
return FALSE;
}
// @@@
bool spec_taxidermist( CHAR_DATA *ch )
{
OBJ_DATA *inv;
int sn;
if ( ch->position != POS_STANDING )
return FALSE;
if ( ch->pIndexData->pShop == 0 ||
time_info.hour < ch->pIndexData->pShop->open_hour ||
time_info.hour > ch->pIndexData->pShop->close_hour )
return FALSE;
for ( inv = ch->carrying; inv != NULL; inv = inv->next_content )
{
if (inv->item_type == ITEM_CORPSE_NPC)
{
if ( ( sn = skill_lookup( "make purse" ) ) >= 0 )
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, inv );
return TRUE;
}
else if (inv->wear_loc == WEAR_NONE && number_percent() < 5)
{
act( "$n suggests you buy $p.", ch, inv, NULL, TO_ROOM );
return TRUE;
}
}
return FALSE;
}
// @@@
/* The start and end piers are hard-coded into Captain Swing. If we need more
ferries we will have to give him something that encodes the vnums and the
current ferry state information */
#define ROOM_VNUM_START 5950
#define ROOM_VNUM_FINISH 5953
#define OBJ_VNUM_TICKET 5953
bool spec_capn_swing( CHAR_DATA *ch )
{
static int state; /* Boat's current state, 0-11 */
static EXIT_DATA *exit_to_boat; /* A 'doorless' door onto the boat,
disconnected when the ferry leaves
and reconnected when it returns. */
int has_ticket; /* Does the PC/Mob have a ticket? */
CHAR_DATA *passenger; /* A passenger */
ROOM_INDEX_DATA *boat = ch->in_room->exit[1]->to_room; /* The boat room */
OBJ_DATA *obj; /* An inv object */
CHAR_DATA *sea_hag; /* A mob which boards the ship at sea */
CHAR_DATA *person; /* A person standing on the dock */
int i;
/* @@@ */
for (i = 0; i < 10; i++)
obj_to_room( create_money( 50 ), boat);
switch(state) {
case 0: /* Check to see if anyone is on the boat */
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
{
state = 1;
send_to_char("Captain Swing says 'All aboard?'.\n\r", passenger);
}
break;
case 1: /* Warn chars on boat they are going to Mahn-Tor */
state = 0;
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
{
state = 2;
send_to_char("Captain Swing says 'Last call for Mahn-Tor!'.\n\r",
passenger);
}
break;
case 2: /* Check for tickets and leave the dock */
state = 0;
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
{
/* We can't require immortals to have a ticket, as they might not
be able to afford one, and also might be able to kill Swing,
leaving the boat adrift until he repops. */
if ( IS_IMMORTAL(passenger) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -