/*************************************************************************** * 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; 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++); switch (GET_CLASS(ch)) { case CLASS_MAGIC_USER :{ if (!*arg) { sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.practices); send_to_char(buf, ch); send_to_char("You can practice any of these spells:\n\r", ch); for(i=0; *spells[i] != '\n'; i++) if (spell_info[i+1].spell_pointer && (spell_info[i+1].min_level_magic <= GET_LEVEL(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("\n\r", ch); } return(TRUE); } number = old_search_block(arg,0,strlen(arg),spells,FALSE); if(number == -1) { send_to_char("You do not know of this spell...\n\r", ch); return(TRUE); } if (GET_LEVEL(ch) < spell_info[number].min_level_magic) { send_to_char("You do not know of this spell...\n\r", ch); return(TRUE); } if (ch->specials.practices <= 0) { send_to_char("You do not seem to be able to practice now.\n\r", ch); return(TRUE); } if (ch->skills[number].learned >= 95) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } break; case CLASS_THIEF: { if (!*arg) { sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.practices); send_to_char(buf, ch); send_to_char("You can practise any of these skills:\n\r", 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("\n\r", 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("\n\r", ch); } return(TRUE); } 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...\n\r", ch); return(TRUE); } if (ch->specials.practices <= 0) { send_to_char("You do not seem to be able to practice now.\n\r", ch); return(TRUE); } if (nnumber == -1) { if (ch->skills[number+SKILL_SNEAK].learned >= 90) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } else { if (ch->skills[nnumber+SKILL_TRIP].learned >= 90) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } } break; case CLASS_CLERIC :{ if (!*arg) { sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.practices); send_to_char(buf, ch); send_to_char("You can practise any of these spells:\n\r", ch); for(i=0; *spells[i] != '\n'; i++) if (spell_info[i+1].spell_pointer && (spell_info[i+1].min_level_cleric <= GET_LEVEL(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("\n\r", ch); } return(TRUE); } number = old_search_block(arg,0,strlen(arg),spells,FALSE); if(number == -1) { send_to_char("You do not know of this spell...\n\r", ch); return(TRUE); } if (GET_LEVEL(ch) < spell_info[number].min_level_cleric) { send_to_char("You do not know of this spell...\n\r", ch); return(TRUE); } if (ch->specials.practices <= 0) { send_to_char("You do not seem to be able to practice now.\n\r", ch); return(TRUE); } if (ch->skills[number].learned >= 95) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } break; case CLASS_WARRIOR: { if (!*arg) { sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.practices); send_to_char(buf, ch); send_to_char("You can practise any of these skills:\n\r", 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("\n\r", 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("\n\r", 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!\n\r", ch); return(TRUE); } if (ch->specials.practices <= 0) { send_to_char("You do not seem to be able to practice now.\n\r", ch); return(TRUE); } if (nnumber == -1) { if (ch->skills[number+SKILL_KICK].learned >= 85) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } else { if (ch->skills[nnumber+SKILL_SECOND_ATTACK].learned >= 85) { send_to_char("You are already learned in this area.\n\r", ch); return(TRUE); } send_to_char("You Practice for a while...\n\r", 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.\n\r", ch); return(TRUE); } } } break; } return (TRUE); } 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.\n\r", ch->specials.practices ); send_to_char( buf, ch ); arg = "foo"; } if ( !str_cmp( arg, "str" ) ) { if ( GET_CLASS(ch) == CLASS_WARRIOR ) cost = 3; pAbility = &ch->abilities.str; pTmpAbility = &ch->tmpabilities.str; } else if ( !str_cmp( arg, "int" ) ) { if ( GET_CLASS(ch) == CLASS_MAGIC_USER ) cost = 3; pAbility = &ch->abilities.intel; pTmpAbility = &ch->tmpabilities.intel; } else if ( !str_cmp( arg, "wis" ) ) { if ( GET_CLASS(ch) == CLASS_CLERIC ) cost = 3; 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" ) ) { if ( GET_CLASS(ch) == CLASS_THIEF ) cost = 3; pAbility = &ch->abilities.dex; pTmpAbility = &ch->tmpabilities.dex; } else { send_to_char( "You can train in: str int wis con dex.\n\r", ch ); return TRUE; } if ( cost > ch->specials.practices ) { send_to_char( "You don't have enough practices.\n\r", ch ); return TRUE; } if ( *pAbility >= 18 || *pTmpAbility >= 18 ) { send_to_char( "That ability is already at maximum.\n\r", ch ); return TRUE; } ch->specials.practices -= cost; *pAbility += 1; *pTmpAbility += 1; send_to_char( "Your ability increases!\n\r", 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'\n\r", 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.\n\r", 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:\n\r", ch); for(pet = world[pet_room].people; pet; pet = pet->next_in_room) { sprintf(buf, "%8d - %s\n\r", 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!\n\r", ch); return(TRUE); } if (GET_GOLD(ch) < (GET_EXP(pet)*3)) { send_to_char("You don't have enough gold!\n\r", 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'\n\r", 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.\n\r", 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 * ******************************************************************** */