home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / spec_procs.c < prev    next >
C/C++ Source or Header  |  1992-11-24  |  30KB  |  1,115 lines

  1. /* ************************************************************************
  2. *  file: spec_procs.c , Special module.                   Part of DIKUMUD *
  3. *  Usage: Procedures handling special procedures for object/room/mobile   *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ************************************************************************* */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10.  
  11. #include "structs.h"
  12. #include "utils.h"
  13. #include "comm.h"
  14. #include "interpreter.h"
  15. #include "handler.h"
  16. #include "db.h"
  17. #include "spells.h"
  18. #include "limits.h"
  19.  
  20. /*   external vars  */
  21.  
  22. extern struct room_data *world;
  23. extern struct char_data *character_list;
  24. extern struct descriptor_data *descriptor_list;
  25. extern struct index_data *obj_index;
  26. extern struct time_info_data time_info;
  27.  
  28.  
  29. /* extern procedures */
  30.  
  31. void hit(struct char_data *ch, struct char_data *victim, int type);
  32. void gain_exp(struct char_data *ch, int gain);
  33.  
  34. /* Data declarations */
  35.  
  36. struct social_type {
  37.   char *cmd;
  38.   int next_line;
  39. };
  40.  
  41.  
  42. /* ********************************************************************
  43. *  Special procedures for rooms                                       *
  44. ******************************************************************** */
  45.  
  46. char *how_good(int percent)
  47. {
  48.     static char buf[256];
  49.  
  50.     if (percent == 0)
  51.         strcpy(buf, " (not learned)");
  52.     else if (percent <= 10)
  53.         strcpy(buf, " (awful)");
  54.     else if (percent <= 20)
  55.         strcpy(buf, " (bad)");
  56.     else if (percent <= 40)
  57.         strcpy(buf, " (poor)");
  58.     else if (percent <= 55)
  59.         strcpy(buf, " (average)");
  60.     else if (percent <= 70)
  61.         strcpy(buf, " (fair)");
  62.     else if (percent <= 80)
  63.         strcpy(buf, " (good)");
  64.     else if (percent <= 85)
  65.         strcpy(buf, " (very good)");
  66.     else
  67.         strcpy(buf, " (Superb)");
  68.  
  69.     return (buf);
  70. }
  71.  
  72. int guild(struct char_data *ch, int cmd, char *arg) {
  73.  
  74.     char arg1[MAX_STRING_LENGTH];
  75.     char buf[MAX_STRING_LENGTH];
  76.     int number, i, percent;
  77.  
  78.     extern char *spells[];
  79.     extern struct spell_info_type spell_info[MAX_SPL_LIST];
  80.     extern struct int_app_type int_app[26];
  81.  
  82.     static char *w_skills[] = {
  83.         "kick",  /* No. 50 */
  84.         "bash",
  85.         "rescue",
  86.         "\n"
  87.     };
  88.  
  89.     static char *t_skills[] = {
  90.         "sneak",   /* No. 45 */
  91.         "hide",
  92.         "steal",
  93.         "backstab",
  94.         "pick",
  95.         "\n"
  96.     };
  97.  
  98.     if ((cmd != 164) && (cmd != 170)) return(FALSE);
  99.  
  100.     for(; *arg==' '; arg++);
  101.  
  102.     switch (GET_CLASS(ch)) {
  103.         case CLASS_MAGIC_USER :{
  104.             if (!*arg) {
  105.                 sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn);
  106.                 send_to_char(buf, ch);
  107.                 send_to_char("You can practise any of these spells:\n\r", ch);
  108.                 for(i=0; *spells[i] != '\n'; i++)
  109.                     if (spell_info[i+1].spell_pointer &&
  110.                         (spell_info[i+1].min_level_magic <= GET_LEVEL(ch))) {
  111.                         send_to_char(spells[i], ch);
  112.                         send_to_char(how_good(ch->skills[i+1].learned), ch);
  113.                         send_to_char("\n\r", ch);
  114.                 }
  115.                 return(TRUE);
  116.             }
  117.  
  118.             number = old_search_block(arg,0,strlen(arg),spells,FALSE);
  119.             if(number == -1) {
  120.                 send_to_char("You do not know of this spell...\n\r", ch);
  121.                 return(TRUE);
  122.             }
  123.             if (GET_LEVEL(ch) < spell_info[number].min_level_magic) {
  124.                 send_to_char("You do not know of this spell...\n\r", ch);
  125.                 return(TRUE);
  126.             }
  127.             if (ch->specials.spells_to_learn <= 0) {
  128.                 send_to_char("You do not seem to be able to practice now.\n\r", ch);
  129.                 return(TRUE);
  130.             }
  131.             if (ch->skills[number].learned >= 95) {
  132.                 send_to_char("You are already learned in this area.\n\r", ch);
  133.                 return(TRUE);
  134.             }
  135.  
  136.             send_to_char("You Practice for a while...\n\r", ch);
  137.             ch->specials.spells_to_learn--;
  138.  
  139.             percent = ch->skills[number].learned+MAX(25,int_app[GET_INT(ch)].learn);
  140.             ch->skills[number].learned = MIN(95, percent);
  141.  
  142.             if (ch->skills[number].learned >= 95) {
  143.                 send_to_char("You are now learned in this area.\n\r", ch);
  144.                 return(TRUE);
  145.             }
  146.  
  147.         } break;
  148.  
  149.         case CLASS_THIEF: {
  150.             if (!*arg) {
  151.                 sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn);
  152.                 send_to_char(buf, ch);
  153.                 send_to_char("You can practise any of these skills:\n\r", ch);
  154.                 for(i=0; *t_skills[i] != '\n';i++) {
  155.                     send_to_char(t_skills[i], ch);
  156.                     send_to_char(how_good(ch->skills[i+45].learned), ch);
  157.                     send_to_char("\n\r", ch);
  158.                 }
  159.                 return(TRUE);
  160.             }
  161.             number = search_block(arg,t_skills,FALSE);
  162.             if(number == -1) {
  163.                 send_to_char("You do not know of this spell...\n\r", ch);
  164.                 return(TRUE);
  165.             }
  166.             if (ch->specials.spells_to_learn <= 0) {
  167.                 send_to_char("You do not seem to be able to practice now.\n\r", ch);
  168.                 return(TRUE);
  169.             }
  170.             if (ch->skills[number+SKILL_SNEAK].learned >= 85) {
  171.                 send_to_char("You are already learned in this area.\n\r", ch);
  172.                 return(TRUE);
  173.             }
  174.             send_to_char("You Practice for a while...\n\r", ch);
  175.             ch->specials.spells_to_learn--;
  176.  
  177.             percent = ch->skills[number+SKILL_SNEAK].learned +
  178.                       MIN(int_app[GET_INT(ch)].learn, 12);
  179.             ch->skills[number+SKILL_SNEAK].learned = MIN(85, percent);
  180.  
  181.             if (ch->skills[number+SKILL_SNEAK].learned >= 85) {
  182.                 send_to_char("You are now learned in this area.\n\r", ch);
  183.                 return(TRUE);
  184.             }
  185.  
  186.         } break;
  187.  
  188.         case CLASS_CLERIC     :{
  189.             if (!*arg) {
  190.                 sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn);
  191.                 send_to_char(buf, ch);
  192.                 send_to_char("You can practise any of these spells:\n\r", ch);
  193.                 for(i=0; *spells[i] != '\n'; i++)
  194.                     if (spell_info[i+1].spell_pointer &&
  195.                        (spell_info[i+1].min_level_cleric <= GET_LEVEL(ch))) {
  196.                         send_to_char(spells[i], ch);
  197.                         send_to_char(how_good(ch->skills[i+1].learned), ch);
  198.                         send_to_char("\n\r", ch);
  199.                 }
  200.                 return(TRUE);
  201.             }
  202.             number = old_search_block(arg,0,strlen(arg),spells,FALSE);
  203.             if(number == -1) {
  204.                 send_to_char("You do not know of this spell...\n\r", ch);
  205.                 return(TRUE);
  206.             }
  207.             if (GET_LEVEL(ch) < spell_info[number].min_level_cleric) {
  208.                 send_to_char("You do not know of this spell...\n\r", ch);
  209.                 return(TRUE);
  210.             }
  211.             if (ch->specials.spells_to_learn <= 0) {
  212.                 send_to_char("You do not seem to be able to practice now.\n\r", ch);
  213.                 return(TRUE);
  214.             }
  215.             if (ch->skills[number].learned >= 95) {
  216.                 send_to_char("You are already learned in this area.\n\r", ch);
  217.                 return(TRUE);
  218.             }
  219.             send_to_char("You Practice for a while...\n\r", ch);
  220.             ch->specials.spells_to_learn--;
  221.  
  222.             percent = ch->skills[number].learned+MAX(25,int_app[GET_INT(ch)].learn);
  223.             ch->skills[number].learned = MIN(95, percent);
  224.  
  225.             if (ch->skills[number].learned >= 95) {
  226.                 send_to_char("You are now learned in this area.\n\r", ch);
  227.                 return(TRUE);
  228.             }
  229.         } break;
  230.  
  231.         case CLASS_WARRIOR: {
  232.             if (!*arg) {
  233.                 sprintf(buf,"You have got %d practice sessions left.\n\r", ch->specials.spells_to_learn);
  234.                 send_to_char(buf, ch);
  235.                 send_to_char("You can practise any of these skills:\n\r", ch);
  236.                 for(i=0; *w_skills[i] != '\n';i++) {
  237.                     send_to_char(w_skills[i], ch);
  238.                     send_to_char(how_good(ch->skills[i+SKILL_KICK].learned), ch);
  239.                     send_to_char("\n\r", ch);
  240.                 }
  241.                 return(TRUE);
  242.             }
  243.             number = search_block(arg, w_skills, FALSE);
  244.             if(number == -1) {
  245.                 send_to_char("You do not have ability to practise this skill!\n\r", ch);
  246.                 return(TRUE);
  247.             }
  248.             if (ch->specials.spells_to_learn <= 0) {
  249.                 send_to_char("You do not seem to be able to practice now.\n\r", ch);
  250.                 return(TRUE);
  251.             }
  252.             if (ch->skills[number+SKILL_KICK].learned >= 80) {
  253.                 send_to_char("You are already learned in this area.\n\r", ch);
  254.                 return(TRUE);
  255.             }
  256.             send_to_char("You Practice for a while...\n\r", ch);
  257.             ch->specials.spells_to_learn--;
  258.  
  259.             percent = ch->skills[number+SKILL_KICK].learned +
  260.                       MIN(12, int_app[GET_INT(ch)].learn);
  261.             ch->skills[number+SKILL_KICK].learned = MIN(80, percent);
  262.  
  263.             if (ch->skills[number+SKILL_KICK].learned >= 80) {
  264.                 send_to_char("You are now learned in this area.\n\r", ch);
  265.                 return(TRUE);
  266.             }
  267.         } break;
  268.     }
  269. }
  270.  
  271.  
  272.  
  273. int dump(struct char_data *ch, int cmd, char *arg) 
  274. {
  275.    struct obj_data *k;
  276.     char buf[100];
  277.    struct char_data *tmp_char;
  278.    int value=0;
  279.  
  280.     void do_drop(struct char_data *ch, char *argument, int cmd);
  281.     char *fname(char *namelist);
  282.  
  283.     for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
  284.     {
  285.         sprintf(buf, "The %s vanish in a puff of smoke.\n\r" ,fname(k->name));
  286.         for(tmp_char = world[ch->in_room].people; tmp_char;
  287.             tmp_char = tmp_char->next_in_room)
  288.             if (CAN_SEE_OBJ(tmp_char, k))
  289.                 send_to_char(buf,tmp_char);
  290.         extract_obj(k);
  291.     }
  292.  
  293.     if(cmd!=60) return(FALSE);
  294.  
  295.     do_drop(ch, arg, cmd);
  296.  
  297.     value = 0;
  298.  
  299.     for(k = world[ch->in_room].contents; k ; k = world[ch->in_room].contents)
  300.     {
  301.         sprintf(buf, "The %s vanish in a puff of smoke.\n\r",fname(k->name));
  302.         for(tmp_char = world[ch->in_room].people; tmp_char;
  303.             tmp_char = tmp_char->next_in_room)
  304.             if (CAN_SEE_OBJ(tmp_char, k))
  305.                 send_to_char(buf,tmp_char);
  306.             value += MAX(1, MIN(50, k->obj_flags.cost/10));
  307.  
  308.         extract_obj(k);
  309.     }
  310.  
  311.     if (value) 
  312.     {
  313.         act("You are awarded for outstanding performance.", FALSE, ch, 0, 0, TO_CHAR);
  314.         act("$n has been awarded for being a good citizen.", TRUE, ch, 0,0, TO_ROOM);
  315.  
  316.         if (GET_LEVEL(ch) < 3)
  317.             gain_exp(ch, value);
  318.         else
  319.             GET_GOLD(ch) += value;
  320.     }
  321. }
  322.  
  323. int mayor(struct char_data *ch, int cmd, char *arg)
  324. {
  325.   static char open_path[] =
  326.     "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
  327.  
  328.   static char close_path[] =
  329.     "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
  330.  
  331. /*
  332.   const struct social_type open_path[] = {
  333.      {"G",0}
  334.   };
  335.  
  336.   static void *thingy = 0;
  337.   static int cur_line = 0;
  338.  
  339.   for (i=0; i < 1; i++)
  340.   {
  341.     if (*(open_path[cur_line].cmd) == '!') {
  342.       i++;
  343.       exec_social(ch, (open_path[cur_line].cmd)+1,
  344.         open_path[cur_line].next_line, &cur_line, &thingy);
  345.   } else {
  346.       exec_social(ch, open_path[cur_line].cmd,
  347.         open_path[cur_line].next_line, &cur_line, &thingy);
  348.   }
  349. */
  350.   static char *path;
  351.   static int index;
  352.   static bool move = FALSE;
  353.  
  354.   void do_move(struct char_data *ch, char *argument, int cmd);
  355.   void do_open(struct char_data *ch, char *argument, int cmd);
  356.   void do_lock(struct char_data *ch, char *argument, int cmd);
  357.   void do_unlock(struct char_data *ch, char *argument, int cmd);
  358.   void do_close(struct char_data *ch, char *argument, int cmd);
  359.  
  360.  
  361.   if (!move) {
  362.         if (time_info.hours == 6) {
  363.       move = TRUE;
  364.       path = open_path;
  365.             index = 0;
  366.     } else if (time_info.hours == 20) {
  367.       move = TRUE;
  368.       path = close_path;
  369.             index = 0;
  370.     }
  371.   }
  372.  
  373.     if (cmd || !move || (GET_POS(ch) < POSITION_SLEEPING) ||
  374.         (GET_POS(ch) == POSITION_FIGHTING))
  375.         return FALSE;
  376.  
  377.   switch (path[index]) {
  378.     case '0' :
  379.     case '1' :
  380.     case '2' :
  381.     case '3' :
  382.       do_move(ch,"",path[index]-'0'+1);
  383.       break;
  384.  
  385.         case 'W' :
  386.             GET_POS(ch) = POSITION_STANDING;
  387.             act("$n awakens and groans loudly.",FALSE,ch,0,0,TO_ROOM);
  388.             break;
  389.  
  390.         case 'S' :
  391.             GET_POS(ch) = POSITION_SLEEPING;
  392.             act("$n lies down and instantly falls asleep.",FALSE,ch,0,0,TO_ROOM);
  393.             break;
  394.  
  395.     case 'a' :
  396.       act("$n says 'Hello Honey!'",FALSE,ch,0,0,TO_ROOM);
  397.       act("$n smirks.",FALSE,ch,0,0,TO_ROOM);
  398.       break;
  399.  
  400.     case 'b' :
  401.       act("$n says 'What a view! I must get something done about that dump!'",
  402.         FALSE,ch,0,0,TO_ROOM);
  403.       break;
  404.  
  405.     case 'c' :
  406.       act("$n says 'Vandals! Youngsters nowadays have no respect for anything!'",
  407.         FALSE,ch,0,0,TO_ROOM);
  408.       break;
  409.  
  410.     case 'd' :
  411.       act("$n says 'Good day, citizens!'", FALSE, ch, 0,0,TO_ROOM);
  412.       break;
  413.  
  414.     case 'e' :
  415.       act("$n says 'I hereby declare the bazaar open!'",FALSE,ch,0,0,TO_ROOM);
  416.       break;
  417.  
  418.     case 'E' :
  419.       act("$n says 'I hereby declare Midgaard closed!'",FALSE,ch,0,0,TO_ROOM);
  420.       break;
  421.  
  422.     case 'O' :
  423.       do_unlock(ch, "gate", 0);
  424.       do_open(ch, "gate", 0);
  425.       break;
  426.  
  427.     case 'C' :
  428.       do_close(ch, "gate", 0);
  429.       do_lock(ch, "gate", 0);
  430.       break;
  431.  
  432.     case '.' :
  433.       move = FALSE;
  434.       break;
  435.  
  436.   }
  437.  
  438.   index++;
  439.   return FALSE;
  440. }
  441.  
  442. /* ********************************************************************
  443. *  General special procedures for mobiles                                      *
  444. ******************************************************************** */
  445.  
  446. /* SOCIAL GENERAL PROCEDURES
  447.  
  448. If first letter of the command is '!' this will mean that the following
  449. command will be executed immediately.
  450.  
  451. "G",n      : Sets next line to n
  452. "g",n      : Sets next line relative to n, fx. line+=n
  453. "m<dir>",n : move to <dir>, <dir> is 0,1,2,3,4 or 5
  454. "w",n      : Wake up and set standing (if possible)
  455. "c<txt>",n : Look for a person named <txt> in the room
  456. "o<txt>",n : Look for an object named <txt> in the room
  457. "r<int>",n : Test if the npc in room number <int>?
  458. "s",n      : Go to sleep, return false if can't go sleep
  459. "e<txt>",n : echo <txt> to the room, can use $o/$p/$N depending on
  460.              contents of the **thing
  461. "E<txt>",n : Send <txt> to person pointed to by thing
  462. "B<txt>",n : Send <txt> to room, except to thing
  463. "?<num>",n : <num> in [1..99]. A random chance of <num>% success rate.
  464.              Will as usual advance one line upon sucess, and change
  465.              relative n lines upon failure.
  466. "O<txt>",n : Open <txt> if in sight.
  467. "C<txt>",n : Close <txt> if in sight.
  468. "L<txt>",n : Lock <txt> if in sight.
  469. "U<txt>",n : Unlock <txt> if in sight.    */
  470.  
  471. /* Execute a social command.                                        */
  472. void exec_social(struct char_data *npc, char *cmd, int next_line,
  473.                  int *cur_line, void **thing)
  474. {
  475.   bool ok;
  476.  
  477.   void do_move(struct char_data *ch, char *argument, int cmd);
  478.   void do_open(struct char_data *ch, char *argument, int cmd);
  479.   void do_lock(struct char_data *ch, char *argument, int cmd);
  480.   void do_unlock(struct char_data *ch, char *argument, int cmd);
  481.   void do_close(struct char_data *ch, char *argument, int cmd);
  482.  
  483.   if (GET_POS(npc) == POSITION_FIGHTING)
  484.     return;
  485.  
  486.   ok = TRUE;
  487.  
  488.   switch (*cmd) {
  489.  
  490.     case 'G' :
  491.       *cur_line = next_line;
  492.       return;
  493.  
  494.     case 'g' :
  495.       *cur_line += next_line;
  496.       return;
  497.  
  498.     case 'e' :
  499.       act(cmd+1, FALSE, npc, *thing, *thing, TO_ROOM);
  500.       break;
  501.  
  502.     case 'E' :
  503.       act(cmd+1, FALSE, npc, 0, *thing, TO_VICT);
  504.       break;
  505.  
  506.     case 'B' :
  507.       act(cmd+1, FALSE, npc, 0, *thing, TO_NOTVICT);
  508.       break;
  509.  
  510.     case 'm' :
  511.       do_move(npc, "", *(cmd+1)-'0'+1);
  512.       break;
  513.  
  514.     case 'w' :
  515.       if (GET_POS(npc) != POSITION_SLEEPING)
  516.         ok = FALSE;
  517.       else
  518.         GET_POS(npc) = POSITION_STANDING;
  519.       break;
  520.  
  521.     case 's' :
  522.       if (GET_POS(npc) <= POSITION_SLEEPING)
  523.         ok = FALSE;
  524.       else
  525.         GET_POS(npc) = POSITION_SLEEPING;
  526.       break;
  527.  
  528.     case 'c' :  /* Find char in room */
  529.       *thing = get_char_room_vis(npc, cmd+1);
  530.       ok = (*thing != 0);
  531.       break;
  532.  
  533.     case 'o' : /* Find object in room */
  534.       *thing = get_obj_in_list_vis(npc, cmd+1, world[npc->in_room].contents);
  535.       ok = (*thing != 0);
  536.       break;
  537.  
  538.     case 'r' : /* Test if in a certain room */
  539.       ok = (npc->in_room == atoi(cmd+1));
  540.       break;
  541.  
  542.     case 'O' : /* Open something */
  543.       do_open(npc, cmd+1, 0);
  544.       break;
  545.  
  546.     case 'C' : /* Close something */
  547.       do_close(npc, cmd+1, 0);
  548.       break;
  549.  
  550.     case 'L' : /* Lock something  */
  551.       do_lock(npc, cmd+1, 0);
  552.       break;
  553.  
  554.     case 'U' : /* UnLock something  */
  555.       do_unlock(npc, cmd+1, 0);
  556.       break;
  557.  
  558.     case '?' : /* Test a random number */
  559.       if (atoi(cmd+1) <= number(1,100))
  560.         ok = FALSE;
  561.       break;
  562.  
  563.     default:
  564.       break;
  565.   }  /* End Switch */
  566.  
  567.   if (ok)
  568.     (*cur_line)++;
  569.   else
  570.     (*cur_line) += next_line;
  571. }
  572.  
  573.  
  574.  
  575. void npc_steal(struct char_data *ch,struct char_data *victim)
  576. {
  577.     int gold;
  578.  
  579.     if(IS_NPC(victim)) return;
  580.     if(GET_LEVEL(victim)>20) return;
  581.  
  582.     if (AWAKE(victim) && (number(0,GET_LEVEL(ch)) == 0)) {
  583.         act("You discover that $n has $s hands in your wallet.",FALSE,ch,0,victim,TO_VICT);
  584.         act("$n tries to steal gold from $N.",TRUE, ch, 0, victim, TO_NOTVICT);
  585.     } else {
  586.         /* Steal some gold coins */
  587.         gold = (int) ((GET_GOLD(victim)*number(1,10))/100);
  588.         if (gold > 0) {
  589.             GET_GOLD(ch) += gold;
  590.             GET_GOLD(victim) -= gold;
  591.         }
  592.     }
  593. }
  594.  
  595.  
  596. int snake(struct char_data *ch, int cmd, char *arg)
  597. {
  598.     void cast_poison( byte level, struct char_data *ch, char *arg, int type,
  599.       struct char_data *tar_ch, struct obj_data *tar_obj );
  600.  
  601.    if(cmd) return FALSE;
  602.  
  603.     if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
  604.     
  605.     if(ch->specials.fighting && 
  606.         (ch->specials.fighting->in_room == ch->in_room) &&
  607.         (number(0,32-GET_LEVEL(ch))==0))
  608.         {
  609.             act("$n bites $N!", 1, ch, 0, ch->specials.fighting, TO_NOTVICT);
  610.             act("$n bites you!", 1, ch, 0, ch->specials.fighting, TO_VICT);
  611.             cast_poison( GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL,
  612.                  ch->specials.fighting, 0);
  613.             return TRUE;
  614.         }
  615.     return FALSE;
  616. }
  617.  
  618. int thief(struct char_data *ch, int cmd, char *arg)
  619. {
  620.     struct char_data *cons;
  621.  
  622.    if(cmd) return FALSE;
  623.  
  624.     if(GET_POS(ch)!=POSITION_STANDING)return FALSE;
  625.  
  626.     for(cons = world[ch->in_room].people; cons; cons = cons->next_in_room )
  627.         if((!IS_NPC(cons)) && (GET_LEVEL(cons)<21) && (number(1,5)==1))
  628.             npc_steal(ch,cons); 
  629.  
  630.     return TRUE;
  631. }
  632.  
  633. int magic_user(struct char_data *ch, int cmd, char *arg)
  634. {
  635.     struct char_data *vict;
  636.  
  637.     void cast_burning_hands( byte level, struct char_data *ch, char *arg, int type,
  638.         struct char_data *victim, struct obj_data *tar_obj );
  639.     void cast_chill_touch( byte level, struct char_data *ch, char *arg, int type,
  640.         struct char_data *victim, struct obj_data *tar_obj );
  641.     void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type,
  642.         struct char_data *victim, struct obj_data *tar_obj );
  643.     void cast_energy_drain( byte level, struct char_data *ch, char *arg, int type,
  644.         struct char_data *victim, struct obj_data *tar_obj );
  645.     void cast_fireball( byte level, struct char_data *ch, char *arg, int type,
  646.         struct char_data *victim, struct obj_data *tar_obj );
  647.     void cast_magic_missile( byte level, struct char_data *ch, char *arg, int type,
  648.         struct char_data *victim, struct obj_data *tar_obj );
  649.     void cast_blindness( byte level, struct char_data *ch, char *arg, int type,
  650.         struct char_data *tar_ch, struct obj_data *tar_obj );
  651.     void cast_curse( byte level, struct char_data *ch, char *arg, int type,
  652.         struct char_data *tar_ch, struct obj_data *tar_obj );
  653.     void cast_sleep( byte level, struct char_data *ch, char *arg, int type,
  654.         struct char_data *tar_ch, struct obj_data *tar_obj );
  655.  
  656.     if(cmd) return FALSE;
  657.  
  658.     if(GET_POS(ch)!=POSITION_FIGHTING) return FALSE;
  659.     
  660.     if(!ch->specials.fighting) return FALSE;
  661.  
  662.  
  663.     /* Find a dude to to evil things upon ! */
  664.  
  665.     for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room )
  666.         if (vict->specials.fighting==ch && number(0,5)==0)
  667.             break;
  668.  
  669.     if (!vict)
  670.         return FALSE;
  671.  
  672.  
  673.     if( (vict!=ch->specials.fighting) && (GET_LEVEL(ch)>13) && (number(0,7)==0) )
  674.     {
  675.         act("$n utters the words 'dilan oso'.", 1, ch, 0, 0, TO_ROOM);
  676.         cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  677.         return TRUE;
  678.     }
  679.  
  680.     if( (GET_LEVEL(ch)>12) && (number(0,6)==0) )
  681.     {
  682.         act("$n utters the words 'gharia miwi'.", 1, ch, 0, 0, TO_ROOM);
  683.         cast_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  684.         return TRUE;
  685.     }
  686.  
  687.     if( (GET_LEVEL(ch)>7) && (number(0,5)==0) )
  688.     {
  689.         act("$n utters the words 'koholian dia'.", 1, ch, 0, 0, TO_ROOM);
  690.         cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  691.         return TRUE;
  692.     }
  693.  
  694.     if( (GET_LEVEL(ch)>12) && (number(0,8)==0) && IS_EVIL(ch))
  695.     {
  696.         act("$n utters the words 'ib er dranker'.", 1, ch, 0, 0, TO_ROOM);
  697.         cast_energy_drain(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  698.         return TRUE;
  699.     }
  700.  
  701.     switch (GET_LEVEL(ch)) {
  702.         case 1:
  703.         case 2:
  704.         case 3:
  705.         case 4:
  706.             act("$n utters the words 'hahili duvini'.", 1, ch, 0, 0, TO_ROOM);
  707.             cast_magic_missile(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  708.             break;
  709.         case 5:
  710.         case 6:
  711.         case 7:
  712.         case 8:
  713.             act("$n utters the words 'grynt oef'.", 1, ch, 0, 0, TO_ROOM);
  714.             cast_burning_hands(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  715.             break;
  716.         case 9:
  717.         case 10:
  718.             act("$n utters the words 'sjulk divi'.", 1, ch, 0, 0, TO_ROOM);
  719.             cast_lightning_bolt(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  720.             break;
  721.         case 11:
  722.         case 12:
  723.         case 13:
  724.         case 14:
  725.             act("$n utters the words 'nasson hof'.", 1, ch, 0, 0, TO_ROOM);
  726.             cast_colour_spray(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  727.             break;
  728.         default:
  729.             act("$n utters the words 'tuborg'.", 1, ch, 0, 0, TO_ROOM);
  730.             cast_fireball(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0);
  731.             break;
  732.     }
  733.     return TRUE;
  734.  
  735. }
  736.  
  737.  
  738. /* ********************************************************************
  739. *  Special procedures for mobiles                                      *
  740. ******************************************************************** */
  741.  
  742. int guild_guard(struct char_data *ch, int cmd, char *arg)
  743. {
  744.     char buf[256], buf2[256];
  745.  
  746.     if (cmd>6 || cmd<1)
  747.         return FALSE;
  748.  
  749.     strcpy(buf,  "The guard humiliates you, and block your way.\n\r");
  750.     strcpy(buf2, "The guard humiliates $n, and blocks $s way.");
  751.  
  752.     if ((ch->in_room == real_room(3017)) && (cmd == 3)) {
  753.         if (GET_CLASS(ch) != CLASS_MAGIC_USER) {
  754.             act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  755.             send_to_char(buf, ch);
  756.             return TRUE;
  757.         }
  758.     } else if ((ch->in_room == real_room(3004)) && (cmd == 1)) {
  759.         if (GET_CLASS(ch) != CLASS_CLERIC) {
  760.             act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  761.             send_to_char(buf, ch);
  762.             return TRUE;
  763.         }
  764.     } else if ((ch->in_room == real_room(3027)) && (cmd == 2)) {
  765.         if (GET_CLASS(ch) != CLASS_THIEF) {
  766.             act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  767.             send_to_char(buf, ch);
  768.             return TRUE;
  769.         }
  770.     } else if ((ch->in_room == real_room(3021)) && (cmd == 2)) {
  771.         if (GET_CLASS(ch) != CLASS_WARRIOR) {
  772.             act(buf2, FALSE, ch, 0, 0, TO_ROOM);
  773.             send_to_char(buf, ch);
  774.             return TRUE;
  775.         }
  776.  
  777.     }
  778.  
  779.     return FALSE;
  780.  
  781. }
  782.  
  783.  
  784.  
  785.  
  786.  
  787. int puff(struct char_data *ch, int cmd, char *arg)
  788. {
  789.     void do_say(struct char_data *ch, char *argument, int cmd);
  790.  
  791.     if (cmd)
  792.         return(0);
  793.  
  794.     switch (number(0, 60))
  795.     {
  796.         case 0:
  797.             do_say(ch, "My god! It's full of stars!", 0);
  798.            return(1);
  799.         case 1:
  800.             do_say(ch, "How'd all those fish get up here?", 0);
  801.             return(1);
  802.         case 2:
  803.             do_say(ch, "I'm a very female dragon.", 0);
  804.             return(1);
  805.         case 3:
  806.             do_say(ch, "I've got a peaceful, easy feeling.", 0);
  807.             return(1);
  808.         default:
  809.             return(0);
  810.     }
  811. }
  812.                     
  813. int fido(struct char_data *ch, int cmd, char *arg)
  814. {
  815.  
  816.     struct obj_data *i, *temp, *next_obj;
  817.  
  818.     if (cmd || !AWAKE(ch))
  819.         return(FALSE);
  820.  
  821.     for (i = world[ch->in_room].contents; i; i = i->next_content) {
  822.         if (GET_ITEM_TYPE(i)==ITEM_CONTAINER && i->obj_flags.value[3]) {
  823.             act("$n savagely devour a corpse.", FALSE, ch, 0, 0, TO_ROOM);
  824.             for(temp = i->contains; temp; temp=next_obj)
  825.             {
  826.                 next_obj = temp->next_content;
  827.                 obj_from_obj(temp);
  828.                 obj_to_room(temp,ch->in_room);
  829.             }
  830.             extract_obj(i);
  831.             return(TRUE);
  832.         }
  833.     }
  834.     return(FALSE);
  835. }
  836.  
  837.  
  838.  
  839. int janitor(struct char_data *ch, int cmd, char *arg)
  840. {
  841.     struct obj_data *i, *temp, *next_obj;
  842.  
  843.     if (cmd || !AWAKE(ch))
  844.         return(FALSE);
  845.  
  846.     for (i = world[ch->in_room].contents; i; i = i->next_content) {
  847.         if (IS_SET(i->obj_flags.wear_flags, ITEM_TAKE) && 
  848.       ((i->obj_flags.type_flag == ITEM_DRINKCON) ||
  849.           (i->obj_flags.cost <= 10))) {
  850.             act("$n picks up some trash.", FALSE, ch, 0, 0, TO_ROOM);
  851.  
  852.             obj_from_room(i);
  853.             obj_to_char(i, ch);
  854.             return(TRUE);
  855.         }
  856.     }
  857.     return(FALSE);
  858. }
  859.  
  860.  
  861. int cityguard(struct char_data *ch, int cmd, char *arg)
  862. {
  863.     struct char_data *tch, *evil;
  864.     int max_evil;
  865.  
  866.     if (cmd || !AWAKE(ch) || (GET_POS(ch) == POSITION_FIGHTING))
  867.         return (FALSE);
  868.  
  869.     max_evil = 1000;
  870.     evil = 0;
  871.  
  872.     for (tch=world[ch->in_room].people; tch; tch = tch->next_in_room) {
  873.         if (tch->specials.fighting) {
  874.          if ((GET_ALIGNMENT(tch) < max_evil) &&
  875.              (IS_NPC(tch) || IS_NPC(tch->specials.fighting))) {
  876.                 max_evil = GET_ALIGNMENT(tch);
  877.                 evil = tch;
  878.             }
  879.         }
  880.     }
  881.  
  882.     if (evil && (GET_ALIGNMENT(evil->specials.fighting) >= 0)) {
  883.         act("$n screams 'PROTECT THE INNOCENT!  BANZAI!!! CHARGE!!! ARARARAGGGHH!'", FALSE, ch, 0, 0, TO_ROOM);
  884.         hit(ch, evil, TYPE_UNDEFINED);
  885.         return(TRUE);
  886.     }
  887.  
  888.     return(FALSE);
  889. }
  890.  
  891.  
  892. int pet_shops(struct char_data *ch, int cmd, char *arg)
  893. {
  894.     char buf[MAX_STRING_LENGTH], pet_name[256];
  895.     int pet_room;
  896.     struct char_data *pet;
  897.  
  898.     pet_room = ch->in_room+1;
  899.  
  900.     if (cmd==59) { /* List */
  901.         send_to_char("Available pets are:\n\r", ch);
  902.         for(pet = world[pet_room].people; pet; pet = pet->next_in_room) {
  903.             sprintf(buf, "%8d - %s\n\r", 3*GET_EXP(pet), pet->player.short_descr);
  904.             send_to_char(buf, ch);
  905.         }
  906.         return(TRUE);
  907.     } else if (cmd==56) { /* Buy */
  908.  
  909.         arg = one_argument(arg, buf);
  910.         arg = one_argument(arg, pet_name);
  911.         /* Pet_Name is for later use when I feel like it */
  912.  
  913.         if (!(pet = get_char_room(buf, pet_room))) {
  914.             send_to_char("There is no such pet!\n\r", ch);
  915.             return(TRUE);
  916.         }
  917.  
  918.         if (GET_GOLD(ch) < (GET_EXP(pet)*3)) {
  919.             send_to_char("You don't have enough gold!\n\r", ch);
  920.             return(TRUE);
  921.         }
  922.  
  923.         GET_GOLD(ch) -= GET_EXP(pet)*3;
  924.  
  925.         pet = read_mobile(pet->nr, REAL);
  926.         GET_EXP(pet) = 0;
  927.         SET_BIT(pet->specials.affected_by, AFF_CHARM);
  928.  
  929.         if (*pet_name) {
  930.             sprintf(buf,"%s %s", pet->player.name, pet_name);
  931.             free(pet->player.name);
  932.             pet->player.name = strdup(buf);        
  933.  
  934.             sprintf(buf,"%sA small sign on a chain around the neck says 'My Name is %s'\n\r",
  935.               pet->player.description, pet_name);
  936.             free(pet->player.description);
  937.             pet->player.description = strdup(buf);
  938.         }
  939.  
  940.         char_to_room(pet, ch->in_room);
  941.         add_follower(pet, ch);
  942.  
  943.         /* Be certain that pet's can't get/carry/use/weild/wear items */
  944.         IS_CARRYING_W(pet) = 1000;
  945.         IS_CARRYING_N(pet) = 100;
  946.  
  947.         send_to_char("May you enjoy your pet.\n\r", ch);
  948.         act("$n bought $N as a pet.",FALSE,ch,0,pet,TO_ROOM);
  949.  
  950.         return(TRUE);
  951.     }
  952.  
  953.     /* All commands except list and buy */
  954.     return(FALSE);
  955. }
  956.  
  957.  
  958. /* Idea of the LockSmith is functionally similar to the Pet Shop */
  959. /* The problem here is that each key must somehow be associated  */
  960. /* with a certain player. My idea is that the players name will  */
  961. /* appear as the another Extra description keyword, prefixed     */
  962. /* by the words 'item_for_' and followed by the player name.     */
  963. /* The (keys) must all be stored in a room which is (virtually)  */
  964. /* adjacent to the room of the lock smith.                       */
  965.  
  966. int pray_for_items(struct char_data *ch, int cmd, char *arg)
  967. {
  968.   char buf[256];
  969.   int key_room, gold;
  970.   bool found;
  971.   struct obj_data *tmp_obj, *obj;
  972.     struct extra_descr_data *ext;
  973.  
  974.     if (cmd != 176) /* You must pray to get the stuff */
  975.         return FALSE;
  976.  
  977.     key_room = 1+ch->in_room;
  978.  
  979.   strcpy(buf, "item_for_");
  980.   strcat(buf, GET_NAME(ch));
  981.  
  982.   gold = 0;
  983.   found = FALSE;
  984.  
  985.   for (tmp_obj = world[key_room].contents; tmp_obj; tmp_obj = tmp_obj->next_content)
  986.     for(ext = tmp_obj->ex_description; ext; ext = ext->next)
  987.       if (str_cmp(buf, ext->keyword) == 0) {
  988.           if (gold == 0) {
  989.              gold = 1;
  990.                act("$n kneels and at the altar and chants a prayer to Odin.",
  991.                      FALSE, ch, 0, 0, TO_ROOM);
  992.                 act("You notice a faint light in Odin's eye.",
  993.                      FALSE, ch, 0, 0, TO_CHAR);
  994.           }
  995.         obj = read_object(tmp_obj->item_number, REAL);
  996.         obj_to_room(obj, ch->in_room);
  997.           act("$p slowly fades into existence.",FALSE,ch,obj,0,TO_ROOM);
  998.           act("$p slowly fades into existence.",FALSE,ch,obj,0,TO_CHAR);
  999.         gold += obj->obj_flags.cost;
  1000.         found = TRUE;
  1001.       }
  1002.  
  1003.  
  1004.   if (found) {
  1005.     GET_GOLD(ch) -= gold;
  1006.     GET_GOLD(ch) = MAX(0, GET_GOLD(ch));
  1007.     return TRUE;
  1008.     }
  1009.  
  1010.   return FALSE;
  1011. }
  1012.  
  1013.  
  1014. /* ********************************************************************
  1015. *  Special procedures for objects                                     *
  1016. ******************************************************************** */
  1017.  
  1018.  
  1019.  
  1020. #define CHAL_ACT \
  1021. "You are torn out of reality!\n\r\
  1022. You roll and tumble through endless voids for what seems like eternity...\n\r\
  1023. \n\r\
  1024. After a time, a new reality comes into focus... you are elsewhere.\n\r"
  1025.  
  1026.  
  1027. int chalice(struct char_data *ch, int cmd, char *arg)
  1028. {
  1029.     /* 222 is the normal chalice, 223 is chalice-on-altar */
  1030.  
  1031.     struct obj_data *chalice;
  1032.     char buf1[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
  1033.     static int chl = -1, achl = -1;
  1034.  
  1035.     if (chl < 1)
  1036.     {
  1037.         chl = real_object(222);
  1038.         achl = real_object(223);
  1039.     }
  1040.  
  1041.     switch(cmd)
  1042.     {
  1043.         case 10:    /* get */
  1044.             if (!(chalice = get_obj_in_list_num(chl,
  1045.                 world[ch->in_room].contents))
  1046.                 && CAN_SEE_OBJ(ch, chalice))
  1047.                 if (!(chalice = get_obj_in_list_num(achl,
  1048.                     world[ch->in_room].contents)) && CAN_SEE_OBJ(ch, chalice))
  1049.                     return(0);
  1050.     
  1051.             /* we found a chalice.. now try to get us */            
  1052.             do_get(ch, arg, cmd);
  1053.             /* if got the altar one, switch her */
  1054.             if (chalice == get_obj_in_list_num(achl, ch->carrying))
  1055.             {
  1056.                 extract_obj(chalice);
  1057.                 chalice = read_object(chl, VIRTUAL);
  1058.                 obj_to_char(chalice, ch);
  1059.             }
  1060.             return(1);
  1061.         break;
  1062.         case 67: /* put */
  1063.             if (!(chalice = get_obj_in_list_num(chl, ch->carrying)))
  1064.                 return(0);
  1065.  
  1066.             argument_interpreter(arg, buf1, buf2);
  1067.             if (!str_cmp(buf1, "chalice") && !str_cmp(buf2, "altar"))
  1068.             {
  1069.                 extract_obj(chalice);
  1070.                 chalice = read_object(achl, VIRTUAL);
  1071.                 obj_to_room(chalice, ch->in_room);
  1072.                 send_to_char("Ok.\n\r", ch);
  1073.             }
  1074.             return(1);
  1075.         break;
  1076.         case 176: /* pray */
  1077.             if (!(chalice = get_obj_in_list_num(achl,
  1078.                 world[ch->in_room].contents)))
  1079.                 return(0);
  1080.  
  1081.             do_action(ch, arg, cmd);  /* pray */
  1082.             send_to_char(CHAL_ACT, ch);
  1083.             extract_obj(chalice);
  1084.             act("$n is torn out of existence!", TRUE, ch, 0, 0, TO_ROOM);
  1085.             char_from_room(ch);
  1086.             char_to_room(ch, real_room(2500));   /* before the fiery gates */
  1087.             do_look(ch, "", 15);
  1088.             return(1);
  1089.         break;
  1090.         default:
  1091.             return(0);
  1092.         break;
  1093.     }
  1094. }
  1095.  
  1096.  
  1097.  
  1098.  
  1099. int kings_hall(struct char_data *ch, int cmd, char *arg)
  1100. {
  1101.     if (cmd != 176)
  1102.         return(0);
  1103.  
  1104.     do_action(ch, arg, 176);
  1105.  
  1106.     send_to_char("You feel as if some mighty force has been offended.\n\r", ch);
  1107.     send_to_char(CHAL_ACT, ch);
  1108.     act("$n is struck by an intense beam of light and vanishes.",
  1109.         TRUE, ch, 0, 0, TO_ROOM);
  1110.     char_from_room(ch);
  1111.     char_to_room(ch, real_room(1420));  /* behind the altar */
  1112.     do_look(ch, "", 15);
  1113.     return(1);
  1114. }
  1115.