/***************************************************************************
* file: spec_pro.c , Special module. Part of DIKUMUD *
* Usage: Procedures handling special procedures for object/room/mobile *
* Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
* *
* Copyright (C) 1992, 1993 Michael Chastain, Michael Quan, Mitchell Tse *
* Performance optimization and bug fixes by MERC Industries. *
* You can use our stuff in any way you like whatsoever so long as this *
* copyright notice remains intact. If you like it please drop a line *
* to mec@garnet.berkeley.edu. *
* *
* This is free software and you are benefitting. We hope that you *
* share your changes too. What goes around, comes around. *
***************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "structs.h"
#include "mob.h"
#include "obj.h"
#include "utils.h"
#include "interp.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "limits.h"
/* external vars */
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct index_data *obj_index;
extern struct time_info_data time_info;
/* extern procedures */
void hit(struct char_data *ch, struct char_data *victim, int type);
void gain_exp(struct char_data *ch, int gain);
void cast_burning_hands( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_chill_touch( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_energy_drain( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_fireball( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_magic_missile( byte level, struct char_data *ch, char *arg, int type,
struct char_data *victim, struct obj_data *tar_obj );
void cast_blindness( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_curse( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_sleep( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_armor( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_bless( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_cure_light( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
/* Dragon breath .. */
void cast_fire_breath( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_frost_breath( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_acid_breath( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_gas_breath( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
void cast_lightning_breath( byte level, struct char_data *ch, char *arg,
int type, struct char_data *tar_ch,
struct obj_data *tar_obj );
/* Data declarations */
struct social_type
{
char *cmd;
int next_line;
};
/* ********************************************************************
* Special procedures for rooms *
******************************************************************** */
char *how_good(int percent)
{
if (percent == 0)
return ( " (not learned)");
if (percent <= 10)
return ( " (awful)");
if (percent <= 20)
return ( " (bad)");
if (percent <= 40)
return ( " (poor)");
if (percent <= 55)
return ( " (average)");
if (percent <= 70)
return ( " (fair)");
if (percent <= 80)
return ( " (good)");
if (percent <= 85)
return ( " (very good)");
return ( " (Superb)");
}
int guild(struct char_data *ch, int cmd, char *arg)
{
char buf[MAX_STRING_LENGTH];
int nnumber, number, i, percent, inguild=0;
extern char *spells[];
extern struct spell_info_type spell_info[MAX_SPL_LIST];
extern struct int_app_type int_app[26];
static char *nw_skills[] = {
"secondattack",
"disarm",
"thirdattack",
"parry",
"\n"
};
static char *nt_skills[] = {
"trip",
"dodge",
"dual",
"disarm",
"\n"
};
static char *w_skills[] = {
"kick", /* No. 50 */
"bash",
"rescue",
"\n"
};
static char *t_skills[] = {
"sneak", /* No. 45 */
"hide",
"steal",
"backstab",
"pick",
"\n"
};
#if 0
static char *ex_skills[] = {
"recall",
"/n"
};
#endif
if ((cmd != 164) && (cmd != 170)) return(FALSE);
for(; *arg==' '; arg++);
inguild=(ch->in_room==real_room(3019)?1:0) +
(ch->in_room==3029?1:0) + (ch->in_room==real_room(3002)?1:0) +
(ch->in_room==3023?1:0);
if (ch->in_room==real_room(3019)||(!*arg&&!inguild)) {
if (!*arg) {
sprintf(buf,"You have got %d practice sessions left.\r\n",
ch->specials.practices);
send_to_char(buf, ch);
/* send_to_char("You can practice any of these spells:\r\n", ch);*/
for(i=0; *spells[i] != '\n'; i++)
if (spell_info[i+1].spell_pointer &&
(spell_info[i+1].min_level_magic <= GET_MM(ch))) {
sprintf(buf," %20s",spells[i]);
send_to_char(buf, ch);
sprintf(buf,"%14s",how_good(ch->skills[i+1].learned));
send_to_char(buf, ch);
sprintf(buf," %4d",use_mana(ch,i+1));
send_to_char(buf, ch);
send_to_char("\r\n", ch);
}
}
else {
number = old_search_block(arg,0,strlen(arg),spells,FALSE);
if(number == -1) {
send_to_char("You do not know of this spell...\r\n", ch);
return(TRUE);
}
if (GET_MM(ch) < spell_info[number].min_level_magic) {
send_to_char("You do not know of this spell...\r\n", ch);
return(TRUE);
}
if (ch->specials.practices <= 0) {
send_to_char("You do not seem to be able to practice now.\r\n", ch);
return(TRUE);
}
if (ch->skills[number].learned >= 95) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[number].learned+MAX(25,int_app[GET_INT(ch)].learn);
ch->skills[number].learned = MIN(95, percent);
if (ch->skills[number].learned >= 95) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
}
}
if (ch->in_room==real_room(3002)||(!*arg&&!inguild)) {
if (!*arg) {
/* sprintf(buf,"You have got %d practice sessions left.\r\n",
ch->specials.practices);
send_to_char(buf, ch);
send_to_char("You can practise any of these spells:\r\n", ch);*/
for(i=0; *spells[i] != '\n'; i++)
if (spell_info[i+1].spell_pointer &&
(spell_info[i+1].min_level_cleric <= GET_CC(ch))) {
sprintf(buf," %20s ",spells[i]);
send_to_char(buf, ch);
sprintf(buf,"%14s",how_good(ch->skills[i+1].learned));
send_to_char(buf, ch);
sprintf(buf," %4d",use_mana(ch,i+1));
send_to_char(buf, ch);
send_to_char("\r\n", ch);
}
}
else {
number = old_search_block(arg,0,strlen(arg),spells,FALSE);
if(number == -1) {
send_to_char("You do not know of this spell...\r\n", ch);
return(TRUE);
}
if (GET_CC(ch) < spell_info[number].min_level_cleric) {
send_to_char("You do not know of this spell...\r\n", ch);
return(TRUE);
}
if (ch->specials.practices <= 0) {
send_to_char("You do not seem to be able to practice now.\r\n", ch);
return(TRUE);
}
if (ch->skills[number].learned >= 95) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[number].learned+MAX(25,int_app[GET_INT(ch)].learn);
ch->skills[number].learned = MIN(95, percent);
if (ch->skills[number].learned >= 95) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
}
}
if (ch->in_room==real_room(3029)||(!*arg&&!inguild)) {
if (!*arg) {
/* sprintf(buf,"You have got %d practice sessions left.\r\n",
ch->specials.practices);
send_to_char(buf, ch);
send_to_char("You can practise any of these skills:\r\n", ch);*/
for(i=0; *t_skills[i] != '\n';i++) {
send_to_char(t_skills[i], ch);
send_to_char(how_good(ch->skills[i+45].learned), ch);
send_to_char("\r\n", ch);
}
for(i=0; *nt_skills[i] != '\n';i++) {
send_to_char(nt_skills[i], ch);
send_to_char(how_good(ch->skills[i+SKILL_TRIP].learned), ch);
send_to_char("\r\n", ch);
}
}
else {
number = search_block(arg,t_skills,FALSE);
nnumber = search_block(arg,nt_skills, FALSE);
if((number == -1) && (nnumber == -1)) {
send_to_char("You do not know of this skill...\r\n", ch);
return(TRUE);
}
if (ch->specials.practices <= 0) {
send_to_char("You do not seem to be able to practice now.\r\n", ch);
return(TRUE);
}
if (nnumber == -1)
{
if (ch->skills[number+SKILL_SNEAK].learned >= 90) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[number+SKILL_SNEAK].learned +
MIN(int_app[GET_INT(ch)].learn, 12);
ch->skills[number+SKILL_SNEAK].learned = MIN(90, percent);
if (ch->skills[number+SKILL_SNEAK].learned >= 90) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
} else
{
if (ch->skills[nnumber+SKILL_TRIP].learned >= 90) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[nnumber+SKILL_TRIP].learned +
MIN(int_app[GET_INT(ch)].learn, 12);
ch->skills[nnumber+SKILL_TRIP].learned = MIN(90, percent);
if (ch->skills[nnumber+SKILL_TRIP].learned >= 90) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
}
}
}
if (ch->in_room==real_room(3023)||(!*arg&&!inguild)) {
if (!*arg) {
/* sprintf(buf,"You have got %d practice sessions left.\r\n",
ch->specials.practices);
send_to_char(buf, ch);
send_to_char("You can practise any of these skills:\r\n", ch);*/
for(i=0; *w_skills[i] != '\n';i++) {
send_to_char(w_skills[i], ch);
send_to_char(how_good(ch->skills[i+SKILL_KICK].learned), ch);
send_to_char("\r\n", ch);
}
for(i=0; *nw_skills[i] != '\n';i++) {
send_to_char(nw_skills[i],ch);
send_to_char(how_good(ch->skills[i+SKILL_SECOND_ATTACK].learned), ch);
send_to_char("\r\n", ch);
}
return(TRUE);
}
number = search_block(arg, w_skills, FALSE);
nnumber = search_block(arg, nw_skills, FALSE);
if((number == -1) && (nnumber == -1)) {
send_to_char("You do not have ability to practise this skill!\r\n", ch);
return(TRUE);
}
if (ch->specials.practices <= 0) {
send_to_char("You do not seem to be able to practice now.\r\n", ch);
return(TRUE);
}
if (nnumber == -1)
{
if (ch->skills[number+SKILL_KICK].learned >= 85) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[number+SKILL_KICK].learned +
MIN(12, int_app[GET_INT(ch)].learn);
ch->skills[number+SKILL_KICK].learned = MIN(85, percent);
if (ch->skills[number+SKILL_KICK].learned >= 85) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
} else
{
if (ch->skills[nnumber+SKILL_SECOND_ATTACK].learned >= 85) {
send_to_char("You are already learned in this area.\r\n", ch);
return(TRUE);
}
send_to_char("You Practice for a while...\r\n", ch);
ch->specials.practices--;
percent = ch->skills[nnumber+SKILL_SECOND_ATTACK].learned +
MIN(12, int_app[GET_INT(ch)].learn);
ch->skills[nnumber+SKILL_SECOND_ATTACK].learned = MIN(85, percent);
if (ch->skills[nnumber+SKILL_SECOND_ATTACK].learned >= 85) {
send_to_char("You are now learned in this area.\r\n", ch);
return(TRUE);
}
}
}
page_string(ch->desc, buf, 1);
return (TRUE);
}
long int GET_CL_COST(struct char_data *ch, int class)
{
int i=1,cost=0;
if (GET_CL(ch)[class]==0)
cost=450;
else
cost=exp_table[(int)GET_CL(ch)[class]+1] - exp_table[(int)GET_CL(ch)[class]];
if(GET_CL(ch)[CLASS_MAGE] >GET_CL(ch)[class]) i*=4;
if(GET_CL(ch)[CLASS_CLERIC] >GET_CL(ch)[class]) i*=4;
if(GET_CL(ch)[CLASS_THIEF] >GET_CL(ch)[class]) i*=4;
if(GET_CL(ch)[CLASS_WARRIOR]>GET_CL(ch)[class]) i*=4;
return(cost * i);
}
int train(struct char_data *ch, int cmd, char *arg)
{
char buf[256];
sbyte *pAbility = NULL;
sbyte *pTmpAbility = NULL;
int cost = 5;
/*
* Check for right command.
* Strip white space on arg.
*/
if ( cmd != 165 )
return FALSE;
while ( *arg == ' ' )
arg++;
if ( *arg == '\0' )
{
sprintf( buf, "You have %d practice sessions left.\r\n",
ch->specials.practices );
send_to_char( buf, ch );
arg = "foo";
}
if ( !str_cmp( arg, "str" ) )
{
pAbility = &ch->abilities.str;
pTmpAbility = &ch->tmpabilities.str;
}
else if ( !str_cmp( arg, "int" ) )
{
pAbility = &ch->abilities.intel;
pTmpAbility = &ch->tmpabilities.intel;
}
else if ( !str_cmp( arg, "wis" ) )
{
pAbility = &ch->abilities.wis;
pTmpAbility = &ch->tmpabilities.wis;
}
else if ( !str_cmp( arg, "con" ) )
{
pAbility = &ch->abilities.con;
pTmpAbility = &ch->tmpabilities.con;
}
else if ( !str_cmp( arg, "dex" ) )
{
pAbility = &ch->abilities.dex;
pTmpAbility = &ch->tmpabilities.dex;
}
else if ( !strncmp( arg, "mage", 1 ) )
{
if (GET_MM(ch)>30) return(1);
cost=GET_CL_COST(ch,CLASS_MAGE);
if (GET_EXP(ch)>cost)
{
GET_EXP(ch) -= cost;
GET_CLASS(ch)=CLASS_MAGE;
advance_level(ch);
send_to_char("You gain a mage level!\r\n",ch);
return(1);
}
else
{
sprintf(buf,"You need %d exp to level..\r\n",cost);
send_to_char(buf,ch);
return(1);
}
}
else if ( !strncmp( arg, "cleric", 1) )
{
if (GET_CC(ch)>30) return(1);
cost=GET_CL_COST(ch,CLASS_CLERIC);
if (GET_EXP(ch)>cost)
{
GET_EXP(ch) -= cost;
GET_CLASS(ch)=CLASS_CLERIC;
advance_level(ch);
send_to_char("You gain a cleric level!\r\n",ch);
return(1);
}
else
{
sprintf(buf,"You need %d exp to level..\r\n",cost);
send_to_char(buf,ch);
return(1);
}
}
else if ( !strncmp( arg, "thief", 1) )
{
if (GET_TT(ch)>30) return(1);
cost=GET_CL_COST(ch,CLASS_THIEF);
if (GET_EXP(ch)>cost)
{
GET_EXP(ch) -= cost;
GET_CLASS(ch)=CLASS_THIEF;
advance_level(ch);
send_to_char("You gain a thief level!\r\n",ch);
return(1);
}
else
{
sprintf(buf,"You need %d exp to level..\r\n",cost);
send_to_char(buf,ch);
return(1);
}
}
else if ( !strncmp( arg, "war", 1 ) )
{
if (GET_WW(ch)>30) return(1);
cost=GET_CL_COST(ch,CLASS_WARRIOR);
if (GET_EXP(ch)>cost)
{
GET_EXP(ch) -= cost;
GET_CLASS(ch)=CLASS_WARRIOR;
advance_level(ch);
send_to_char("You gain a warrior level!\r\n",ch);
return(1);
}
else
{
sprintf(buf,"You need %d exp to level..\r\n",cost);
send_to_char(buf,ch);
return(1);
}
}
else
{
send_to_char( "You can train in: str int wis con dex.\r\n", ch );
send_to_char( "You can also level in classes for these amounts:\r\n",ch);
sprintf(buf, "%-9s: %9ld\r\n%-9s: %9ld\r\n%-9s: %9ld\r\n%-9s: %9ld\r\n",
"Mage",GET_CL_COST(ch,CLASS_MAGE),
"Cleric",GET_CL_COST(ch,CLASS_CLERIC),
"Thief",GET_CL_COST(ch,CLASS_THIEF),
"Warrior",GET_CL_COST(ch,CLASS_WARRIOR));
send_to_char(buf,ch);
return TRUE;
}
if ( cost > ch->specials.practices )
{
send_to_char( "You don't have enough practices.\r\n", ch );
return TRUE;
}
if ( *pAbility >= 20 || *pTmpAbility >= 25 )
{
send_to_char( "That ability is already at maximum.\r\n", ch );
return TRUE;
}
ch->specials.practices -= cost;
*pAbility += 1;
*pTmpAbility += 1;
send_to_char( "Your ability increases!\r\n", ch );
return TRUE;
}
int mayor(struct char_data *ch, int cmd, char *arg)
{
static char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
static char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
static char *path;
static int index;
static bool move = FALSE;
void do_move(struct char_data *ch, char *argument, int cmd);
void do_open(struct char_data *ch, char *argument, int cmd);
void do_lock(struct char_data *ch, char *argument, int cmd);
void do_unlock(struct char_data *ch, char *argument, int cmd);
void do_close(struct char_data *ch, char *argument, int cmd);
if (!move) {
if (time_info.hours == 6) {
move = TRUE;
path = open_path;
index = 0;
} else if (time_info.hours == 20) {
move = TRUE;
path = close_path;
index = 0;
}
}
if (cmd || !move || (GET_POS(ch) < POSITION_SLEEPING) ||
(GET_POS(ch) == POSITION_FIGHTING))
return FALSE;
switch (path[index]) {
case '0' :
case '1' :
case '2' :
case '3' :
do_move(ch,"",path[index]-'0'+1);
break;
case 'W' :
GET_POS(ch) = POSITION_STANDING;
act("$n awakens and groans loudly.",
FALSE,ch,0,0,TO_ROOM);
break;
case 'S' :
GET_POS(ch) = POSITION_SLEEPING;
act("$n lies down and instantly falls asleep.",
FALSE,ch,0,0,TO_ROOM);
break;
case 'a' :
act("$n says 'Hello Honey!'",FALSE,ch,0,0,TO_ROOM);
act("$n smirks.",FALSE,ch,0,0,TO_ROOM);
break;
case 'b' :
act("$n says 'What a view! I must get something done about that dump!'",
FALSE,ch,0,0,TO_ROOM);
break;
case 'c' :
act(
"$n says 'Vandals! Youngsters nowadays have no respect for anything!'",
FALSE,ch,0,0,TO_ROOM);
break;
case 'd' :
act("$n says 'Good day, citizens!'", FALSE, ch, 0,0,TO_ROOM);
break;
case 'e' :
act("$n says 'I hereby declare the bazaar open!'",FALSE,ch,0,0,TO_ROOM);
break;
case 'E' :
act("$n says 'I hereby declare Midgaard closed!'",FALSE,ch,0,0,TO_ROOM);
break;
case 'O' :
do_unlock(ch, "gate", 0);
do_open(ch, "gate", 0);
break;
case 'C' :
do_close(ch, "gate", 0);
do_lock(ch, "gate", 0);
break;
case '.' :
move = FALSE;
break;
}
index++;
return FALSE;
}
/* ********************************************************************
* General special procedures for mobiles *
******************************************************************** */
/* SOCIAL GENERAL PROCEDURES
If first letter of the command is '!' this will mean that the following
command will be executed immediately.
"G",n : Sets next line to n
"g",n : Sets next line relative to n, fx. line+=n
"m<dir>",n : move to <dir>, <dir> is 0,1,2,3,4 or 5
"w",n : Wake up and set standing (if possible)
"c<txt>",n : Look for a person named <txt> in the room
"o<txt>",n : Look for an object named <txt> in the room
"r<int>",n : Test if the npc in room number <int>?
"s",n : Go to sleep, return false if can't go sleep
"e<txt>",n : echo <txt> to the room, can use $o/$p/$N depending on
contents of the **thing
"E<txt>",n : Send <txt> to person pointed to by thing
"B<txt>",n : Send <txt> to room, except to thing
"?<num>",n : <num> in [1..99]. A random chance of <num>% success rate.
Will as usual advance one line upon sucess, and change
relative n lines upon failure.
"O<txt>",n : Open <txt> if in sight.
"C<txt>",n : Close <txt> if in sight.
"L<txt>",n : Lock <txt> if in sight.
"U<txt>",n : Unlock <txt> if in sight. */
/* Execute a social command. */
void exec_social(struct char_data *npc, char *cmd, int next_line,
int *cur_line, void **thing)
{
bool ok;
void do_move(struct char_data *ch, char *argument, int cmd);
void do_open(struct char_data *ch, char *argument, int cmd);
void do_lock(struct char_data *ch, char *argument, int cmd);
void do_unlock(struct char_data *ch, char *argument, int cmd);
void do_close(struct char_data *ch, char *argument, int cmd);
if (GET_POS(npc) == POSITION_FIGHTING)
return;
ok = TRUE;
switch (*cmd) {
case 'G' :
*cur_line = next_line;
return;
case 'g' :
*cur_line += next_line;
return;
case 'e' :
act(cmd+1, FALSE, npc, *thing, *thing, TO_ROOM);
break;
case 'E' :
act(cmd+1, FALSE, npc, 0, *thing, TO_VICT);
break;
case 'B' :
act(cmd+1, FALSE, npc, 0, *thing, TO_NOTVICT);
break;
case 'm' :
do_move(npc, "", *(cmd+1)-'0'+1);
break;
case 'w' :
if (GET_POS(npc) != POSITION_SLEEPING)
ok = FALSE;
else
GET_POS(npc) = POSITION_STANDING;
break;
case 's' :
if (GET_POS(npc) <= POSITION_SLEEPING)
ok = FALSE;
else
GET_POS(npc) = POSITION_SLEEPING;
break;
case 'c' : /* Find char in room */
*thing = get_char_room_vis(npc, cmd+1);
ok = (*thing != 0);
break;
case 'o' : /* Find object in room */
*thing = get_obj_in_list_vis(npc, cmd+1, world[npc->in_room].contents);
ok = (*thing != 0);
break;
case 'r' : /* Test if in a certain room */
ok = (npc->in_room == atoi(cmd+1));
break;
case 'O' : /* Open something */
do_open(npc, cmd+1, 0);
break;
case 'C' : /* Close something */
do_close(npc, cmd+1, 0);
break;
case 'L' : /* Lock something */
do_lock(npc, cmd+1, 0);
break;
case 'U' : /* UnLock something */
do_unlock(npc, cmd+1, 0);
break;
case '?' : /* Test a random number */
if (atoi(cmd+1) <= number(1,100))
ok = FALSE;
break;
default:
break;
} /* End Switch */
if (ok)
(*cur_line)++;
else
(*cur_line) += next_line;
}
void npc_steal(struct char_data *ch,struct char_data *victim)
{
int gold;
if(IS_NPC(victim)) return;
if(GET_LEVEL(victim)>20) return;
if (AWAKE(victim) && (number(0,GET_LEVEL(ch)) == 0)) {
act("You discover that $n has $s hands in your wallet.",
FALSE,ch,0,victim,TO_VICT);
act("$n tries to steal gold from $N.",TRUE, ch, 0, victim, TO_NOTVICT);
} else {
/* Steal some gold coins */
gold = (int) ((GET_GOLD(victim)*number(1,10))/100);
if (gold > 0) {
GET_GOLD(ch) += gold;
GET_GOLD(victim) -= gold;
}
}
}
int snake(struct char_data *ch, int cmd, char *arg)
{
void cast_poison( byte level, struct char_data *ch, char *arg, int type,
struct char_data *tar_ch, struct obj_data *tar_obj );
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if ( ch->specials.fighting &&
(ch->specials.fighting->in_room == ch->in_room) &&
number(0 , 99) < 2 * GET_LEVEL(ch) )
{
act("You bite $N!", 1, ch, 0, ch->specials.fighting, TO_CHAR);
act("$n bites $N!", 1, ch, 0, ch->specials.fighting, TO_NOTVICT);
act("$n bites you!", 1, ch, 0, ch->specials.fighting, TO_VICT);
cast_poison( GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL,
ch->specials.fighting, 0);
return TRUE;
}
return FALSE;
}
int thief(struct char_data *ch, int cmd, char *arg)
{
struct char_data *cons;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_STANDING)return FALSE;
for(cons = world[ch->in_room].people; cons; cons = cons->next_in_room )
if((!IS_NPC(cons)) && (GET_LEVEL(cons)<32) && (number(1,5)==1))
npc_steal(ch,cons);
return TRUE;
}
int magic_user(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to do evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch && number(0,2)==0)
break;
if (!vict)
return FALSE;
if( vict!=ch->specials.fighting && GET_LEVEL(ch)>13 && number(0,7)==0 )
{
act("$n utters the words 'dilan oso'.", 1, ch, 0, 0, TO_ROOM);
cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,6)==0) )
{
act("$n utters the words 'gharia miwi'.", 1, ch, 0, 0, TO_ROOM);
cast_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>7) && (number(0,5)==0) )
{
act("$n utters the words 'koholian dia'.", 1, ch, 0, 0, TO_ROOM);
cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
if( (GET_LEVEL(ch)>12) && (number(0,8)==0) && IS_EVIL(ch))
{
act("$n utters the words 'ib er dranker'.", 1, ch, 0, 0, TO_ROOM);
cast_energy_drain(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
switch (GET_LEVEL(ch)) {
case 1:
case 2:
case 3:
case 4:
act("$n utters the words 'hahili duvini'.", 1, ch, 0, 0, TO_ROOM);
cast_magic_missile(
GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 5:
case 6:
case 7:
case 8:
act("$n utters the words 'grynt oef'.", 1, ch, 0, 0, TO_ROOM);
cast_burning_hands(
GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 9:
case 10:
act("$n utters the words 'sjulk divi'.", 1, ch, 0, 0, TO_ROOM);
cast_lightning_bolt(
GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
case 11:
case 12:
case 13:
case 14:
act("$n utters the words 'nasson hof'.", 1, ch, 0, 0, TO_ROOM);
cast_colour_spray(
GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
default:
act("$n utters the words 'tuborg'.", 1, ch, 0, 0, TO_ROOM);
cast_fireball(
GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
break;
}
return TRUE;
}
int Thalos_citizen(struct char_data *ch, int cmd, char *arg)
{
void do_say(struct char_data *ch, char *argument, int cmd);
struct char_data *vict;
if (!AWAKE(ch))
return FALSE;
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
if (vict->specials.fighting==ch && number(0,1)==0)
break;
if (!vict)
return FALSE;
switch (number(0,20))
{
case 0 : do_say(ch, "Thalos must be the safest city around.", 0);
return TRUE;
case 1 : do_say(ch, "Don't you just love these lamia pets?", 0);
do_say(ch, "They must be god's gift to man.", 0);
return TRUE;
case 2 : do_say(ch, "Hello, neighbor. How's the weather?", 0);
return TRUE;
case 3 : do_say(ch, "Thalos is built to last. Don't you think?", 0);
return TRUE;
case 4 : do_say(ch, "Our lamia pets will do anything.", 0);
do_say(ch, "Make our beds, serv our meals, wash the dishes,...", 0);
return TRUE;
case 5 : do_say(ch, "Have you seen the cute little beholder in", 0);
do_say(ch, "the temple. He's so cuuuute!", 0);
return TRUE;
case 6 : do_say(ch, "Oh, don't worry about the old man at the", 0);
do_say(ch, "guild house. He's insane.", 0);
return TRUE;
case 7 : do_say(ch, "That's a mighty big weapon you have there.", 0);
do_say(ch, "Off to hunt a bear?", 0);
return TRUE;
default : return FALSE;
}
}
int baby_troll(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
void do_say(struct char_data *ch, char *argument, int cmd);
if (cmd) return FALSE;
if (!AWAKE(ch))
return FALSE;
if (!ch->specials.fighting) {
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
if (number(0,1)==0)
break;
if (!vict)
return FALSE;
switch (number(0,15))
{
case 1 :
act( "The baby troll says, 'Wana play?'",TRUE, vict, 0, 0, TO_ROOM);
break;
case 2 :
act("The baby troll says, 'Come sit down and play with us.'",
TRUE, vict, 0, 0, TO_ROOM);
break;
case 3 :
act("The baby troll throws something greasy and grimey at $n!",\
TRUE, vict, 0, 0, TO_ROOM);
act("The baby troll throws something greasy and grimey at you!",
TRUE,vict,0,0,TO_CHAR);
break;
default:
return FALSE;
}
}
return FALSE;
}
int Fanatic_Hector(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
void do_say(struct char_data *ch, char *argument, int cmd);
void do_emote(struct char_data *ch, char *argument, int cmd);
if (cmd || !AWAKE(ch))
return FALSE;
if (ch->specials.fighting)
return TRUE;
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
if (number(0,1)==0)
break;
if (!vict)
return FALSE;
switch (number(0,15))
{
case 1 : do_say(ch, "The end of the world is comming! Beware!", 0);
return TRUE;
case 2 : do_say(ch, "To arms! To arms! Darkness is here!", 0);
return TRUE;
case 3 : do_emote(ch,
"waves his right fist covered in golden silk at you.", 0);
return TRUE;
case 4 : do_emote(ch, "spits on the banner of Thalos with disgust.", 0);
return TRUE;
default:
return FALSE;
}
}
int Executioner(struct char_data *ch, int cmd, char *arg)
{
struct char_data *tch;
struct char_data *mob;
char buf[MAX_INPUT_LENGTH];
char *strName;
if (cmd || !AWAKE(ch))
return FALSE;
for ( tch = world[ch->in_room].people; tch; tch = tch->next_in_room )
{
if ( IS_SET(tch->specials.affected_by, AFF_KILLER) )
strName = "KILLER";
else if ( IS_SET(tch->specials.affected_by, AFF_THIEF) )
strName = "THIEF";
else
continue;
sprintf( buf,
"%s is a %s! PROTECT THE INNOCENT! MORE BLOOOOD!!!",
GET_NAME(tch),
strName );
do_shout( ch, buf, 0 );
hit( ch, tch, TYPE_UNDEFINED );
mob = read_mobile( real_mobile(3060), REAL );
char_to_room( mob, ch->in_room );
mob = read_mobile( real_mobile(3060), REAL );
char_to_room( mob, ch->in_room );
break;
}
return FALSE;
}
int red_dragon(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
return FALSE;
if (cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to do evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch && number(0,1)==0){
act("$n breathes fire.",1, ch, 0, 0, TO_ROOM);
cast_fire_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
}
if (!vict)
if (number(0,1) == 0){
act("$n breathes fire.",1, ch, 0, 0, TO_ROOM);
cast_fire_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL,
ch->specials.fighting, 0);
}
return TRUE;
}
int white_dragon(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
return FALSE;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to do evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch && number(0,1)==0){
act("$n breathes frost.",1, ch, 0, 0, TO_ROOM);
cast_frost_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
}
if (!vict)
if (number(0,1) == 0){
act("$n breathes frost.",1, ch, 0, 0, TO_ROOM);
cast_frost_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL,
ch->specials.fighting, 0);
}
return TRUE;
}
int black_dragon(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
return FALSE;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to do evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
if (vict->specials.fighting==ch && number(0,2)==0)
break;
if (!vict)
{
if (number(0,1) == 0)
{
vict = ch->specials.fighting;
if (vict == NULL)
return FALSE;
}
else
return FALSE;
}
act("$n breathes acid.",1, ch, 0, 0, TO_ROOM);
cast_acid_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
int blue_dragon(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
return FALSE;
if(cmd) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
/* Find a dude to do evil things upon ! */
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
if (vict->specials.fighting==ch && number(0,2)==0)
break;
if (!vict)
{
if (number(0,1) == 0)
{
vict = ch->specials.fighting;
if (vict == NULL)
return FALSE;
}
else
return FALSE;
}
act("$n breathes lightning.",1, ch, 0, 0, TO_ROOM);
cast_lightning_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
int green_dragon(struct char_data *ch, int cmd, char *arg)
{
return FALSE;
if ( cmd ) return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if(!ch->specials.fighting) return FALSE;
if(number(0,1)==0) return FALSE;
act("$n breathes gas.",1, ch, 0, 0, TO_ROOM);
cast_gas_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, 0, 0);
return TRUE;
}
int brass_dragon(struct char_data *ch, int cmd, char *arg)
{
struct char_data *vict;
return FALSE;
if ( cmd == 4 && ch->in_room == real_room(5065) )
{
act( "The brass dragon says '$n isn't invited'",
FALSE, ch, 0, 0, TO_ROOM );
send_to_char( "The brass dragon says 'you're not invited'\r\n", ch );
return TRUE;
}
if ( cmd )
return FALSE;
if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
if (!ch->specials.fighting) return FALSE;
if (number(0,1)==0)
{
act("$n breathes gas.",1,ch, 0, 0, TO_ROOM);
cast_gas_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, 0, 0);
return TRUE;
}
for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
if (vict->specials.fighting==ch && number(0,1)==0)
break;
if (!vict)
{
if (number(0,1) == 0)
{
vict = ch->specials.fighting;
if (vict == NULL)
return FALSE;
}
else
return FALSE;
}
act("$n breathes lightning.",1, ch, 0, 0, TO_ROOM);
cast_lightning_breath(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
return TRUE;
}
/* ********************************************************************
* Special procedures for mobiles *
******************************************************************** */
int guild_guard(struct char_data *ch, int cmd, char *arg)
{
if (cmd>6 || cmd<1)
return FALSE;
/* if ( ( GET_CLASS(ch) != CLASS_MAGIC_USER
&& ch->in_room == real_room(3017) && cmd == 3 )
|| ( GET_CLASS(ch) != CLASS_CLERIC
&& ch->in_room == real_room(3004) && cmd == 1 )
|| ( GET_CLASS(ch) != CLASS_THIEF
&& ch->in_room == real_room(3027) && cmd == 2 )
|| ( GET_CLASS(ch) != CLASS_WARRIOR
&& ch->in_room == real_room(3021) && cmd == 2 )
)
{
act( "The guard humiliates $n, and blocks $s way.",
FALSE, ch, 0, 0, TO_ROOM );
send_to_char(
"The guard humiliates you, and blocks your way.\r\n", ch );
return TRUE;
}
*/
return FALSE;
}
int puff(struct char_data *ch, int cmd, char *arg)
{
void do_say(struct char_data *ch, char *argument, int cmd);
if (cmd)
return(0);
switch (number(0, 12))
{
case 5:
do_say(ch, "My god! It's full of stars!", 0);
return(1);
case 2:
do_say(ch, "How'd all those fish get up here?", 0);
return(1);
case 8:
do_say(ch, "I'm a very female dragon.", 0);
return(1);
case 9:
do_say(ch, "I've got a peaceful, easy feeling.", 0);
return(1);
default:
return(0);
}
}
int fido(struct char_data *ch, int cmd, char *arg)
{
struct obj_data *i, *temp, *next_obj;
if (cmd || !AWAKE(ch))
return(FALSE);
for (i = world[ch->in_room].contents; i; i = i->next_content) {
if (GET_ITEM_TYPE(i)==ITEM_CONTAINER && i->obj_flags.value[3]) {
act("$n savagely devours a corpse.", FALSE, ch, 0, 0, TO_ROOM);
for(temp = i->contains; temp; temp=next_obj)
{
next_obj = temp->next_content;
obj_from_obj(temp);
obj_to_room(temp,ch->in_room);
}
extract_obj(i);
return(TRUE);
}
}
return(FALSE);
}
int janitor(struct char_data *ch, int cmd, char *arg)
{
struct obj_data *i;
if (cmd || !AWAKE(ch))
return(FALSE);
for (i = world[ch->in_room].contents; i; i = i->next_content) {
if (IS_SET(i->obj_flags.wear_flags, ITEM_TAKE) &&
((i->obj_flags.type_flag == ITEM_DRINKCON) ||
(i->obj_flags.cost <= 10))) {
act("$n picks up some trash.", FALSE, ch, 0, 0, TO_ROOM);
obj_from_room(i);
obj_to_char(i, ch);
return(TRUE);
}
}
return(FALSE);
}
int cityguard(struct char_data *ch, int cmd, char *arg)
{
struct char_data *tch, *evil;
int max_evil;
char buf[100];
if (cmd || !AWAKE(ch) || (GET_POS(ch) == POSITION_FIGHTING))
return (FALSE);
max_evil = 300;
evil = 0;
for (tch=world[ch->in_room].people; tch; tch = tch->next_in_room) {
if(IS_SET(tch->specials.affected_by, AFF_KILLER)) {
sprintf(buf,
"%s is a KILLER! PROTECT THE INNOCENT! BANZAI!!! CHARGE!!! ARARARAGGGHH!",
GET_NAME(tch));
do_shout(ch, buf, 0);
hit(ch, tch, TYPE_UNDEFINED);
return (TRUE);
} else
if (IS_SET(tch->specials.affected_by, AFF_THIEF)) {
sprintf(buf,
"%s is a THIEF! PROTECT THE INNOCENT! BANZAI!!! CHARGE!!! ARARARAGGGHH!",
GET_NAME(tch));
do_shout(ch, buf, 0);
hit(ch, tch, TYPE_UNDEFINED);
return (TRUE);
}
if (tch->specials.fighting) {
if ((GET_ALIGNMENT(tch) < max_evil) &&
(IS_NPC(tch) || IS_NPC(tch->specials.fighting))) {
max_evil = GET_ALIGNMENT(tch);
evil = tch;
}
}
}
if (evil && !IS_EVIL(evil->specials.fighting))
{
act(
"$n screams 'PROTECT THE INNOCENT! BANZAI!!! CHARGE!!! ARARARAGGGHH!'",
FALSE, ch, 0, 0, TO_ROOM);
hit(ch, evil, TYPE_UNDEFINED);
return(TRUE);
}
return(FALSE);
}
int adept(struct char_data *ch, int cmd, char *arg)
{
struct char_data *tch;
void do_say(struct char_data *ch, char *argument, int cmd);
if (cmd || !AWAKE(ch))
return(FALSE);
for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room)
if(!IS_NPC(tch) && number (0,2) == 1 && CAN_SEE(ch,tch))
break;
if (!tch)
return FALSE;
switch (number (0,10))
{
case 3 :
act("$n utters the words 'garf'.", 1, ch, 0, 0, TO_ROOM);
cast_cure_light(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, tch, 0);
return (1);
case 7 :
act("$n utters the words 'nahk'.", 1, ch, 0, 0, TO_ROOM);
cast_bless(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, tch, 0);
return (1);
case 6 :
act("$n utters the words 'tehctah'.", 1, ch, 0, 0, TO_ROOM);
cast_armor(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, tch, 0);
return (1);
case 4 :
do_say(ch,"Finish school. Don't drop out.", 0);
return (1);
case 5 :
do_say(ch,"Move it. Others want to go to this school.", 0);
return (1);
default:
return (0);
}
}
int mud_school_adept(struct char_data *ch, int cmd, char *arg)
{
struct char_data *tch;
void do_say(struct char_data *ch, char *argument, int cmd);
if (cmd)
return (0);
if (!AWAKE(ch))
return (0);
for (tch = world[ch->in_room].people; tch; tch = tch->next_in_room)
if(!IS_NPC(tch) && number (0,2) == 1 && CAN_SEE(ch,tch))
break;
if (!tch)
return (0);
switch (number(0,20))
{
case 15 :
do_say(ch,"What are you staring at?", 0);
return(1);
case 18 :
do_say(ch,"Hi, I'm your friend.", 0);
return(1);
case 3 :
do_say(ch,"Isn't this a fine school?", 0);
return(1);
case 12 :
do_say(ch,"Finish school. Dont drop out.", 0);
return(1);
case 5 :
do_say(ch,"Move it. Others want to go to this school.", 0);
return(1);
case 6 :
do_say(ch,"Be careful, don't get killed by those monsters!", 0);
return(1);
case 7 :
do_say(ch,"Don't forget to wear your clothes, young students!", 0);
return(1);
case 8 :
do_say(ch,"What are you doing just STANDING there?!?!!?", 0);
do_say(ch,"GET going!", 0);
return(1);
case 9 :
do_say(ch,"Hello....Hello, are you listening to me?", 0);
return(1);
default:
return(0);
}
}
int MERCling(struct char_data *ch, int cmd, char *arg)
{
void do_shout(struct char_data *ch, char *argument, int cmd);
if (cmd)
return(0);
switch (number(0, 12))
{
case 0:
do_shout(ch, "Happy Birthday to Hatchet! Happy Birthday to me!", 0);
return(1);
case 1:
do_shout(ch, "Happy Birthday to Kahn! Happy Birthday to you!", 0);
return(1);
case 2:
do_shout(ch, "Happy Birthday to Hatchet! Happy Birthday to you!", 0);
return(1);
case 3:
do_shout(ch, "Happy Birthday to Kahn! Happy Birthday to me!", 0);
return(1);
default:
return(0);
}
}
/*********************************************************************
* Special procedures for shops *
*********************************************************************/
int pet_shops(struct char_data *ch, int cmd, char *arg)
{
char buf[MAX_STRING_LENGTH], pet_name[256];
int pet_room;
struct char_data *pet;
pet_room = ch->in_room+1;
if (cmd==59) { /* List */
send_to_char("Available pets are:\r\n", ch);
for(pet = world[pet_room].people; pet; pet = pet->next_in_room) {
sprintf(buf, "%8d - %s\r\n",
3*GET_EXP(pet), pet->player.short_descr);
send_to_char(buf, ch);
}
return(TRUE);
} else if (cmd==56) { /* Buy */
arg = one_argument(arg, buf);
arg = one_argument(arg, pet_name);
/* Pet_Name is for later use when I feel like it */
if (!(pet = get_char_room(buf, pet_room))) {
send_to_char("There is no such pet!\r\n", ch);
return(TRUE);
}
if (GET_GOLD(ch) < (GET_EXP(pet)*3)) {
send_to_char("You don't have enough gold!\r\n", ch);
return(TRUE);
}
GET_GOLD(ch) -= GET_EXP(pet)*3;
/*
* Should be some code here to defend against weird monsters
* getting loaded into the pet shop back room. -- Furey
*/
pet = read_mobile(pet->nr, REAL);
GET_EXP(pet) = 0;
SET_BIT(pet->specials.affected_by, AFF_CHARM);
if (*pet_name) {
sprintf(buf,"%s %s", pet->player.name, pet_name);
free(pet->player.name);
pet->player.name = str_dup(buf);
sprintf( buf,
"%sA small sign on a chain around the neck says 'My Name is %s'\r\n",
pet->player.description, pet_name);
free(pet->player.description);
pet->player.description = str_dup(buf);
}
char_to_room(pet, ch->in_room);
add_follower(pet, ch);
/* Be certain that pet's can't get/carry/use/weild/wear items */
IS_CARRYING_W(pet) = 1000;
IS_CARRYING_N(pet) = 100;
send_to_char("May you enjoy your pet.\r\n", ch);
act("$n bought $N as a pet.",FALSE,ch,0,pet,TO_ROOM);
return(TRUE);
}
/* All commands except list and buy */
return(FALSE);
}
/* Idea of the LockSmith is functionally similar to the Pet Shop */
/* The problem here is that each key must somehow be associated */
/* with a certain player. My idea is that the players name will */
/* appear as the another Extra description keyword, prefixed */
/* by the words 'item_for_' and followed by the player name. */
/* The (keys) must all be stored in a room which is (virtually) */
/* adjacent to the room of the lock smith. */
/* ********************************************************************
* Special procedures for objects *
******************************************************************** */