📄 special.c
字号:
has_ticket = 1;
state = 3;
send_to_char( "Captain Swing has comped you.\n\r",
passenger );
}
else
{
/* Check for a valid ferry ticket. */
has_ticket = 0;
for ( obj = passenger->carrying; obj; obj = obj->next_content )
{
if ( obj->pIndexData->vnum == OBJ_VNUM_TICKET )
{
has_ticket = 1;
state = 3;
extract_obj( obj );
send_to_char( "Captain Swing collects your ticket.\n\r",
passenger );
}
}
}
if (!has_ticket)
{
send_to_char( "Captain Swing notices you have no ticket and hurls"
" you into the air.\n\r", passenger );
act( "$n is hurtled off by an angry Captain Swing.",
passenger, NULL, NULL, TO_ROOM );
char_from_room( passenger );
char_to_room( passenger, boat->exit[3]->to_room );
act( "$n crashes to the ground.", passenger, NULL, NULL, TO_ROOM );
send_to_char( "You hit the ground, hard!\n\r", passenger);
do_look( passenger, "auto" );
}
}
/* Close and lock the pick-proof door, to prevent players from trying to
kill Captain Swing. They shouldn't even be able to see him unless
they teleport into his room... */
SET_BIT(boat->exit[3]->exit_info, EX_CLOSED|EX_LOCKED);
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
send_to_char("Captain Swing has secured the door.\n\r"
"You feel the boat begin to rock as it leaves the dock.\n\r",
passenger);
/* Remove the boat from the dock's list of exits */
exit_to_boat = get_room_index( ROOM_VNUM_START )->exit[1];
get_room_index( ROOM_VNUM_START )->exit[1] = 0;
/* Let people on the dock know the boat has left without them */
for ( person = get_room_index( ROOM_VNUM_START )->people;
person;
person = person->next_in_room )
send_to_char("A ship pulls away from the dock.\n\r", person);
state = 3;
break;
case 3: /* Boring. Makes the boat ride take a long time */
case 4:
case 5:
case 6:
case 8:
case 9:
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
send_to_char("You begin to feel seasick as"
" the ferry rocks up and down.\n\r", passenger);
state++;
break;
case 7: /* A sea monster invades the ship! */
if ( number_percent() < 33 )
{
sea_hag = create_mobile( get_mob_index(7041) );
char_to_room( sea_hag, boat );
act( "The porthole opens and $n climbs through!", sea_hag, NULL, NULL,
TO_ROOM );
}
state++;
break;
case 10: /* The boat lands at the far pier. (There is no way to board) */
REMOVE_BIT(boat->exit[3]->exit_info, EX_CLOSED|EX_LOCKED);
boat->exit[3]->to_room = get_room_index( ROOM_VNUM_FINISH );
for ( passenger = boat->people;
passenger;
passenger = passenger->next_in_room )
send_to_char("You feel a gentle thud as the ferry docks.\n\r"
"Captain Swing opens the door and motions you to leave.\n\r",
passenger);
for ( person = get_room_index( ROOM_VNUM_FINISH )->people;
person;
person = person->next_in_room )
send_to_char("A ship pulls into the dock.\n\r", person);
state = 11;
break;
case 11: /* Get passengers off the boat so it can return to Midgaard */
state = 0;
for ( passenger = boat->people; passenger;
passenger = passenger->next_in_room )
{
/* The boat will not return until all passengers debark */
state = 11;
send_to_char("Captain Swing reminds you to debark promptly.\n\r",
passenger);
}
/* Did the boat return? */
if (state == 0)
{
/* The boat is now back at the start pier */
boat->exit[3]->to_room = get_room_index( ROOM_VNUM_START );
/* Add the boat to the dock's list of exits */
get_room_index( ROOM_VNUM_START )->exit[1] = exit_to_boat;
for ( person = get_room_index( ROOM_VNUM_START )->people;
person;
person = person->next_in_room )
send_to_char("A ship pulls into the dock.\n\r", person);
}
break;
}
return FALSE;
}
bool spec_snake_charm( CHAR_DATA *ch )
{
CHAR_DATA *victim;
CHAR_DATA *v_next;
char *spell;
int sn;
if ( ch->position != POS_FIGHTING )
{
switch ( number_bits( 3 ) ) {
case 0:
do_order( ch, "all sing charmer" ); /* a chance to get free here */
break;
case 1:
do_order( ch,
"all chat 'The snake charmer area is pretty cool. "
"I'm getting a lot of experience really fast!" );
break;
case 2:
do_order( ch,
"all chat 'YES! I just got 327xp for killing the snake charmer!");
break;
case 3:
do_order( ch, "all remove dagger" );
do_order( ch, "all give dagger charmer" );
break;
case 4:
do_order( ch, "all remove sword" );
do_order( ch, "all give sword charmer" );
break;
case 5:
do_order( ch, "all remove mace" );
do_order( ch, "all give mace charmer" );
break;
case 6:
do_order( ch, "all drop all" );
break;
case 7:
do_order( ch, "all cast 'cure light' charmer" );
break;
};
return TRUE;
}
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if ( victim->fighting == ch && number_bits( 2 ) == 0 )
break;
}
if ( victim == NULL )
return FALSE;
act( "$n begins playing a new, beautiful song.", ch, NULL, NULL, TO_ROOM );
spell_charm_person(gsn_charm_person, ch->level, ch, victim );
if (IS_AFFECTED(victim, AFF_CHARM))
stop_fighting( victim, TRUE );
// do_flee( victim, "" );
// do_rest( victim, "" );
// do_order( ch, "all rest" );
return TRUE;
}
bool spec_hunger( CHAR_DATA *ch )
{
CHAR_DATA *victim;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( !IS_AWAKE(ch) )
return FALSE;
for ( victim = ch->in_room->people; victim; victim = victim->next_in_room )
if ( number_bits( 2 ) == 0 )
break;
if ( victim == NULL )
return FALSE;
if ( !IS_NPC(victim) )
victim->pcdata->condition[COND_FULL] = 0;
for ( obj = victim->carrying; obj; obj = obj_next )
{
obj_next = obj->next_content;
if ( obj->item_type == ITEM_FOOD )
{
extract_obj( obj );
act( "Chomp!", ch, NULL, NULL, TO_ROOM );
}
}
act( "$n looks a little healthier.", ch, NULL, NULL, TO_ROOM );
return TRUE;
}
// @@@ ###
/*
spec_cast_from_list-
I copied the basic structure from spec_cast_undead. The first time any
mobile with this vnum gets pulsed, the cargo for this mobile vnum is
initialized. From then on, the mobile will cast spells in it's cargo.
*/
struct string_cargo_struct {
int ncount;
char *string_list[16]; /* Allow up to 16 spells / mobile vnum */
};
void check_init_cargo( CHAR_DATA *ch )
{
struct string_cargo_struct *cls;
if (ch->pIndexData->cargo == 0)
{
/* remove the @ from the mobile's description */
char *q = strchr(ch->pIndexData->description, '@');
int ncount = 0;
// Allocate the cargo
ch->pIndexData->cargo = cls = alloc_perm( sizeof (*cls) );
/* Is there a spell cargo? */
if (q)
{
/* count the spells */
while (*q)
{
*q++ = '\0'; /* Break descr after @ into spell text */
while (isspace(*q))
q++;
if (*q)
{
if (ncount < 16)
cls->string_list[ncount++] = q;
while (*q && *q != '\n')
// {
// if (*q == '_') /* fix _ in spell names to a space */
// *q = ' ';
q++;
// }
}
}
}
cls->ncount = ncount;
}
}
bool spec_cast_from_list( CHAR_DATA *ch )
{
CHAR_DATA *victim;
CHAR_DATA *v_next;
char *spell;
int sn;
struct string_cargo_struct *cls;
int nwhich;
/* Do we need to initialize cargo? */
check_init_cargo(ch);
cls = ch->pIndexData->cargo;
if ( ch->position != POS_FIGHTING || cls->ncount == 0)
return FALSE;
for ( victim = ch->in_room->people; victim != NULL; victim = v_next )
{
v_next = victim->next_in_room;
if ( victim->fighting == ch && number_bits( 2 ) == 0 )
break;
}
if ( victim == NULL )
return FALSE;
// Calculate the spell randomly from mobile's table
nwhich = number_range(0, cls->ncount-1);
sn = skill_lookup( cls->string_list[nwhich] );
if (sn < 0)
return FALSE;
/* If the spell is defensive, the mobile casts on itself. This allows it
to heal itself, bless itself, etc. All other spells are cast on the
character the mob is fighting. For offensive spells that is cool. For
SELF spells it's not cool, if the mob casts 'STONE SKIN' say it will be
on the victim, not itself. This is to allow TELEPORT to teleport the
victim away, like mages do. Good idea? I don't know...
If the spell has no target, like 'EARTHQUAKE', it is probably a bad idea
to have the mobile cast it... The spell is probably coded to hit all
NPCs... */
if (skill_table[sn].target == TAR_CHAR_DEFENSIVE)
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, ch );
else
(*skill_table[sn].spell_fun) ( sn, ch->level, ch, victim );
return TRUE;
}
bool spec_shopkeeper( CHAR_DATA *ch )
{
OBJ_DATA *inv;
struct string_cargo_struct *cls;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
if ( !IS_AWAKE(ch) || ch->position != POS_STANDING )
return FALSE;
cls = ch->pIndexData->cargo;
for ( inv = ch->carrying; inv != NULL; inv = inv->next_content )
{
int npercent = (cls->ncount >= 2) ? atoi(cls->string_list[1]) : 5;
if (inv->wear_loc == WEAR_NONE && number_percent() < npercent)
{
if (cls->ncount)
act( cls->string_list[0], ch, inv, NULL, TO_ROOM );
else
act( "$n suggests you buy a $p.", ch, inv, NULL, TO_ROOM );
return TRUE;
}
}
return FALSE;
}
// @@@ Modify to take a list of objects
bool spec_obj_bribe( CHAR_DATA *ch )
{
OBJ_DATA *inv;
int nobjvnum;
struct string_cargo_struct *cls;
char *p;
char buf[MAX_STRING_LENGTH];
sh_int old_trust;
/* Make sure the cargo was safely initialized */
check_init_cargo(ch);
if ( ch->position != POS_STANDING )
return FALSE;
cls = ch->pIndexData->cargo;
if (!IS_AWAKE(ch) || cls->ncount < 2)
return FALSE;
for (p = cls->string_list[0]; *p; )
{
nobjvnum = atoi(p);
for ( inv = ch->carrying; inv != NULL; inv = inv->next_content )
{
if (inv->pIndexData->vnum == nobjvnum)
{
int nwhich = number_range(1, cls->ncount-1);
char *q;
extract_obj( inv );
q = p = cls->string_list[nwhich];
if (*p)
for ( ;; )
{
if (*p == ';' || *p == '\0')
{
memcpy(buf, q, p-q);
buf[p-q] = '\0';
old_trust = ch->trust;
ch->trust = 55; /* Safe on TFC? */
interpret(ch, buf);
ch->trust = old_trust;
if (*p == '\0')
return TRUE;
q = p+1;
}
p++;
}
}
}
while (*p && *p != ' ')
p++;
if (*p)
p++;
}
return FALSE;
}
OBJ_DATA *is_wielding(CHAR_DATA *victim, char *vnum_list)
{
OBJ_DATA *obj;
int nobjvnum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -