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 / spell_parser.c < prev    next >
C/C++ Source or Header  |  1991-03-01  |  30KB  |  910 lines

  1. /* ************************************************************************
  2. *  file: spell_parser.c , Basic routines and parsing      Part of DIKUMUD *
  3. *  Usage : Interpreter of spells                                          *
  4. *  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
  5. ************************************************************************* */
  6.  
  7. #include <stdio.h>
  8. #include <assert.h>
  9.  
  10. #include "structs.h"
  11. #include "utils.h"
  12. #include "comm.h"
  13. #include "db.h"
  14. #include "interpreter.h" 
  15. #include "spells.h"
  16. #include "handler.h"
  17.  
  18. #define MANA_MU 1
  19. #define MANA_CL 1
  20.  
  21. #define SPELLO(nr, beat, pos, mlev, clev, mana, tar, func) { \
  22.     spell_info[nr].spell_pointer = (func);    \
  23.     spell_info[nr].beats = (beat);            \
  24.     spell_info[nr].minimum_position = (pos);  \
  25.     spell_info[nr].min_usesmana = (mana);     \
  26.     spell_info[nr].min_level_cleric = (clev); \
  27.     spell_info[nr].min_level_magic = (mlev);  \
  28.     spell_info[nr].targets = (tar);           \
  29. }
  30.  
  31. #define SPELL_LEVEL(ch, sn)               \
  32.   ( (GET_CLASS(ch) == CLASS_CLERIC) ?     \
  33.   spell_info[sn].min_level_cleric : spell_info[sn].min_level_magic)
  34.  
  35.  
  36. /* 100 is the MAX_MANA for a character */
  37. #define USE_MANA(ch, sn)                            \
  38.   MAX(spell_info[sn].min_usesmana, 100/(2+GET_LEVEL(ch)-SPELL_LEVEL(ch,sn)))
  39.  
  40. /* Global data */
  41.  
  42. extern struct room_data *world;
  43. extern struct char_data *character_list;
  44. extern char *spell_wear_off_msg[];
  45.  
  46.  
  47. /* Extern procedures */
  48.  
  49. char *strdup(char *str);
  50.  
  51. /* Extern procedures */
  52. void cast_armor( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  53. void cast_teleport( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  54. void cast_bless( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  55. void cast_blindness( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  56. void cast_burning_hands( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  57. void cast_call_lightning( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  58. void cast_charm_person( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  59. void cast_chill_touch( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  60. void cast_shocking_grasp( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  61. void cast_clone( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  62. void cast_colour_spray( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  63. void cast_control_weather( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  64. void cast_create_food( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  65. void cast_create_water( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  66. void cast_cure_blind( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  67. void cast_cure_critic( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  68. void cast_cure_light( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  69. void cast_curse( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  70. void cast_detect_evil( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  71. void cast_detect_invisibility( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  72. void cast_detect_magic( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  73. void cast_detect_poison( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  74. void cast_dispel_evil( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  75. void cast_earthquake( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  76. void cast_enchant_weapon( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  77. void cast_energy_drain( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  78. void cast_fireball( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  79. void cast_harm( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  80. void cast_heal( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  81. void cast_invisibility( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  82. void cast_lightning_bolt( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  83. void cast_locate_object( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  84. void cast_magic_missile( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  85. void cast_poison( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  86. void cast_protection_from_evil( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  87. void cast_remove_curse( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  88. void cast_sanctuary( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  89. void cast_sleep( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  90. void cast_strength( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  91. void cast_summon( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  92. void cast_ventriloquate( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  93. void cast_word_of_recall( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  94. void cast_remove_poison( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  95. void cast_sense_life( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  96. void cast_identify( byte level, struct char_data *ch, char *arg, int si, struct char_data *tar_ch, struct obj_data *tar_obj);
  97.  
  98.  
  99.  
  100. struct spell_info_type spell_info[MAX_SPL_LIST];
  101.  
  102. char *spells[]=
  103. {
  104.    "armor",               /* 1 */
  105.    "teleport",
  106.    "bless",
  107.    "blindness",
  108.    "burning hands",
  109.    "call lightning",
  110.    "charm person",
  111.    "chill touch",
  112.    "clone",
  113.    "colour spray",
  114.    "control weather",     /* 11 */
  115.    "create food",
  116.    "create water",
  117.    "cure blind",
  118.    "cure critic",
  119.    "cure light",
  120.    "curse",
  121.    "detect evil",
  122.    "detect invisibility",
  123.    "detect magic",
  124.    "detect poison",       /* 21 */
  125.    "dispel evil",
  126.    "earthquake",
  127.    "enchant weapon",
  128.    "energy drain",
  129.    "fireball",
  130.    "harm",
  131.    "heal",
  132.    "invisibility",
  133.    "lightning bolt",
  134.    "locate object",      /* 31 */
  135.    "magic missile",
  136.    "poison",
  137.    "protection from evil",
  138.    "remove curse",
  139.    "sanctuary",
  140.    "shocking grasp",
  141.    "sleep",
  142.    "strength",
  143.    "summon",
  144.    "ventriloquate",      /* 41 */
  145.    "word of recall",
  146.    "remove poison",
  147.    "sense life",         /* 44 */
  148.  
  149.    /* RESERVED SKILLS */
  150.    "SKILL_SNEAK",        /* 45 */
  151.    "SKILL_HIDE",
  152.    "SKILL_STEAL",
  153.    "SKILL_BACKSTAB",
  154.    "SKILL_PICK_LOCK",
  155.    "SKILL_KICK",         /* 50 */
  156.    "SKILL_BASH",
  157.    "SKILL_RESCUE",
  158.    /* NON-CASTABLE SPELLS (Scrolls/potions/wands/staffs) */
  159.  
  160.    "identify",           /* 53 */
  161.    "\n"
  162. };
  163.  
  164.  
  165. const byte saving_throws[4][5][25] = {
  166. {
  167.   {16,14,14,14,14,14,13,13,13,13,13,11,11,11,11,11,10,10,10,10,10, 8, 6, 4, 0},
  168.   {13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 3, 2, 1, 0},
  169.   {15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 5, 4, 2, 0},
  170.   {17,15,15,15,15,15,13,13,13,13,13,11,11,11,11,11, 9, 9, 9, 9, 9, 7, 5, 3, 0},
  171.   {14,12,12,12,12,12,10,10,10,10,10, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 4, 3, 2, 0}
  172. }, {
  173.   {11,10,10,10, 9, 9, 9, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 2, 2, 2, 2, 1, 0},
  174.   {16,14,14,14,13,13,13,11,11,11,10,10,10, 9, 9, 9, 8, 8, 8, 6, 6, 5, 4, 3, 0},
  175.   {15,13,13,13,12,12,12,10,10,10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 5, 4, 3, 2, 0},
  176.   {18,16,16,16,15,15,15,13,13,13,12,12,12,11,11,11,10,10,10, 8, 8, 7, 6, 5, 0},
  177.   {17,15,15,15,14,14,14,12,12,12,11,11,11,10,10,10, 9, 9, 9, 7, 7, 6, 5, 4, 0}
  178. }, {
  179.   {15,13,13,13,13,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 7, 6, 0},
  180.   {16,14,14,14,14,12,12,12,12,10,10,10,10, 8, 8, 8, 8, 6, 6, 6, 6, 4, 3, 2, 0},
  181.   {14,12,12,12,12,11,11,11,11,10,10,10,10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 5, 3, 0},
  182.   {18,16,16,16,16,15,15,15,15,14,14,14,14,13,13,13,13,12,12,12,12,11, 9, 5, 0},
  183.   {17,15,15,15,15,13,13,13,13,11,11,11,11, 9, 9, 9, 9, 7, 7, 7, 7, 5, 3, 1, 0}
  184. }, {
  185.   {16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 1, 0},
  186.   {18,16,16,15,15,13,13,12,12,10,10, 9, 9, 7, 7, 6, 6, 5, 5, 5, 5, 4, 3, 2, 0},
  187.   {17,15,15,14,14,12,12,11,11, 9, 9, 8, 8, 6, 6, 5, 5, 4, 4, 4, 4, 3, 2, 1, 0},
  188.   {20,17,17,16,16,13,13,12,12, 9, 9, 8, 8, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 1, 0},
  189.   {19,17,17,16,16,14,14,13,13,11,11,10,10, 8, 8, 7, 7, 6, 6, 6, 6, 4, 2, 1, 0}
  190. }
  191. };
  192.  
  193.  
  194.  
  195. void affect_update( void )
  196. {
  197.     static struct affected_type *af, *next_af_dude;
  198.     static struct char_data *i;
  199.  
  200.     for (i = character_list; i; i = i->next)
  201.         for (af = i->affected; af; af = next_af_dude) {
  202.             next_af_dude = af->next;
  203.             if (af->duration >= 1)
  204.                 af->duration--;
  205.             else {
  206.                 if ((af->type > 0) && (af->type <= 52)) /* It must be a spell */
  207.                     if (!af->next || (af->next->type != af->type) ||
  208.                         (af->next->duration > 0))
  209.                         if (*spell_wear_off_msg[af->type]) {
  210.                             send_to_char(spell_wear_off_msg[af->type], i);
  211.                             send_to_char("\n\r", i);
  212.                         }
  213.  
  214.                 affect_remove(i, af);
  215.             }
  216.         }
  217. }
  218.  
  219.  
  220. void clone_char(struct char_data *ch)
  221. {
  222.     extern struct index_data *mob_index;
  223.     struct char_data *clone;
  224.     struct affected_type *af;
  225.     int i;
  226.  
  227.     CREATE(clone, struct char_data, 1);
  228.  
  229.  
  230.     clear_char(clone);       /* Clear EVERYTHING! (ASSUMES CORRECT) */
  231.  
  232.     clone->player    = ch->player;
  233.     clone->abilities = ch->abilities;
  234.  
  235.     for (i=0; i<5; i++)
  236.         clone->specials.apply_saving_throw[i] = ch->specials.apply_saving_throw[i];
  237.  
  238.     for (af=ch->affected; af; af = af->next)
  239.         affect_to_char(clone, af);
  240.  
  241.     for (i=0; i<3; i++)
  242.         GET_COND(clone,i) = GET_COND(ch, i);
  243.  
  244.     clone->points = ch->points;
  245.  
  246.     for (i=0; i<MAX_SKILLS; i++)
  247.         clone->skills[i] = ch->skills[i];
  248.  
  249.     clone->specials = ch->specials;
  250.     clone->specials.fighting = 0;
  251.  
  252.     GET_NAME(clone) = strdup(GET_NAME(ch));
  253.  
  254.     clone->player.short_descr =    strdup(ch->player.short_descr);
  255.  
  256.     clone->player.long_descr = strdup(ch->player.long_descr);
  257.  
  258.     clone->player.description = 0;
  259.     /* REMEMBER EXTRA DESCRIPTIONS */
  260.  
  261.     GET_TITLE(clone) = strdup(GET_TITLE(ch));
  262.  
  263.     clone->nr = ch->nr;
  264.  
  265.     if (IS_NPC(clone))
  266.         mob_index[clone->nr].number++;
  267.     else { /* Make PC's into NPC's */
  268.         clone->nr = -1;
  269.         SET_BIT(clone->specials.act, ACT_ISNPC);
  270.     }
  271.  
  272.     clone->desc = 0;
  273.     clone->followers = 0;
  274.     clone->master = 0;
  275.  
  276.     clone->next = character_list;
  277.     character_list = clone;
  278.  
  279.     char_to_room(clone, ch->in_room);
  280. }
  281.  
  282.  
  283.  
  284. void clone_obj(struct obj_data *obj)
  285. {
  286.     struct obj_data *clone;
  287.     struct extra_descr_data *ed, temp;
  288.  
  289.  
  290.     CREATE(clone, struct obj_data, 1);
  291.  
  292.     *clone = *obj;
  293.  
  294.     clone->name               = strdup(obj->name);
  295.     clone->description        = strdup(obj->description);
  296.     clone->short_description  = strdup(obj->short_description);
  297.     clone->action_description = strdup(obj->action_description);
  298.     clone->ex_description     = 0;
  299.  
  300.     /* REMEMBER EXTRA DESCRIPTIONS */
  301.     clone->carried_by         = 0;
  302.     clone->in_obj             = 0;
  303.     clone->contains           = 0;
  304.     clone->next_content       = 0;
  305.     clone->next               = 0;
  306.  
  307.     /* VIRKER IKKE ENDNU */
  308. }
  309.  
  310.  
  311.  
  312. /* Check if making CH follow VICTIM will create an illegal */
  313. /* Follow "Loop/circle"                                    */
  314. bool circle_follow(struct char_data *ch, struct char_data *victim)
  315. {
  316.     struct char_data *k;
  317.  
  318.     for(k=victim; k; k=k->master) {
  319.         if (k == ch)
  320.             return(TRUE);
  321.     }
  322.  
  323.     return(FALSE);
  324. }
  325.  
  326.  
  327.  
  328. /* Called when stop following persons, or stopping charm */
  329. /* This will NOT do if a character quits/dies!!          */
  330. void stop_follower(struct char_data *ch)
  331. {
  332.     struct follow_type *j, *k;
  333.  
  334.     assert(ch->master);
  335.  
  336.     if (IS_AFFECTED(ch, AFF_CHARM)) {
  337.         act("You realize that $N is a jerk!", FALSE, ch, 0, ch->master, TO_CHAR);
  338.         act("$n realizes that $N is a jerk!", FALSE, ch, 0, ch->master, TO_NOTVICT);
  339.         act("$n hates your guts!", FALSE, ch, 0, ch->master, TO_VICT);
  340.         if (affected_by_spell(ch, SPELL_CHARM_PERSON))
  341.             affect_from_char(ch, SPELL_CHARM_PERSON);
  342.     } else {
  343.         act("You stop following $N.", FALSE, ch, 0, ch->master, TO_CHAR);
  344.         act("$n stops following $N.", FALSE, ch, 0, ch->master, TO_NOTVICT);
  345.         act("$n stops following you.", FALSE, ch, 0, ch->master, TO_VICT);
  346.     }
  347.  
  348.     if (ch->master->followers->follower == ch) { /* Head of follower-list? */
  349.         k = ch->master->followers;
  350.         ch->master->followers = k->next;
  351.         free(k);
  352.     } else { /* locate follower who is not head of list */
  353.         for(k = ch->master->followers; k->next->follower!=ch; k=k->next)  ;
  354.  
  355.         j = k->next;
  356.         k->next = j->next;
  357.         free(j);
  358.     }
  359.  
  360.     ch->master = 0;
  361.     REMOVE_BIT(ch->specials.affected_by, AFF_CHARM | AFF_GROUP);
  362. }
  363.  
  364.  
  365.  
  366. /* Called when a character that follows/is followed dies */
  367. void die_follower(struct char_data *ch)
  368. {
  369.     struct follow_type *j, *k;
  370.  
  371.     if (ch->master)
  372.         stop_follower(ch);
  373.  
  374.     for (k=ch->followers; k; k=j) {
  375.         j = k->next;
  376.         stop_follower(k->follower);
  377.     }
  378. }
  379.  
  380.  
  381.  
  382. /* Do NOT call this before having checked if a circle of followers */
  383. /* will arise. CH will follow leader                               */
  384. void add_follower(struct char_data *ch, struct char_data *leader)
  385. {
  386.     struct follow_type *k;
  387.  
  388.     assert(!ch->master);
  389.  
  390.     ch->master = leader;
  391.  
  392.     CREATE(k, struct follow_type, 1);
  393.  
  394.     k->follower = ch;
  395.     k->next = leader->followers;
  396.     leader->followers = k;
  397.  
  398.     act("You now follow $N.", FALSE, ch, 0, leader, TO_CHAR);
  399.     act("$n starts following you.", TRUE, ch, 0, leader, TO_VICT);
  400.     act("$n now follows $N.", TRUE, ch, 0, leader, TO_NOTVICT);
  401. }
  402.  
  403.  
  404.  
  405. say_spell( struct char_data *ch, int si )
  406. {
  407.     char buf[MAX_STRING_LENGTH], splwd[MAX_BUF_LENGTH];
  408.     char buf2[MAX_STRING_LENGTH];
  409.  
  410.     int j, offs;
  411.     struct char_data *temp_char;
  412.  
  413.  
  414.     struct syllable {
  415.         char org[10];
  416.         char new[10];
  417.     };
  418.  
  419.     struct syllable syls[] = {
  420.     { " ", " " },
  421.     { "ar", "abra"   },
  422.     { "au", "kada"    },
  423.     { "bless", "fido" },
  424.   { "blind", "nose" },
  425.   { "bur", "mosa" },
  426.     { "cu", "judi" },
  427.     { "de", "oculo"},
  428.     { "en", "unso" },
  429.     { "light", "dies" },
  430.     { "lo", "hi" },
  431.     { "mor", "zak" },
  432.     { "move", "sido" },
  433.   { "ness", "lacri" },
  434.   { "ning", "illa" },
  435.     { "per", "duda" },
  436.     { "ra", "gru"   },
  437.   { "re", "candus" },
  438.     { "son", "sabru" },
  439.   { "tect", "infra" },
  440.     { "tri", "cula" },
  441.     { "ven", "nofo" },
  442.     {"a", "a"},{"b","b"},{"c","q"},{"d","e"},{"e","z"},{"f","y"},{"g","o"},
  443.     {"h", "p"},{"i","u"},{"j","y"},{"k","t"},{"l","r"},{"m","w"},{"n","i"},
  444.     {"o", "a"},{"p","s"},{"q","d"},{"r","f"},{"s","g"},{"t","h"},{"u","j"},
  445.     {"v", "z"},{"w","x"},{"x","n"},{"y","l"},{"z","k"}, {"",""}
  446.     };
  447.  
  448.  
  449.  
  450.     strcpy(buf, "");
  451.     strcpy(splwd, spells[si-1]);
  452.  
  453.     offs = 0;
  454.  
  455.     while(*(splwd+offs)) {
  456.         for(j=0; *(syls[j].org); j++)
  457.             if (strncmp(syls[j].org, splwd+offs, strlen(syls[j].org))==0) {
  458.                 strcat(buf, syls[j].new);
  459.                 if (strlen(syls[j].org))
  460.                     offs+=strlen(syls[j].org);
  461.                 else
  462.                     ++offs;
  463.             }
  464.     }
  465.  
  466.  
  467.     sprintf(buf2,"$n utters the words, '%s'", buf);
  468.     sprintf(buf, "$n utters the words, '%s'", spells[si-1]);
  469.  
  470.     for(temp_char = world[ch->in_room].people;
  471.         temp_char;
  472.         temp_char = temp_char->next_in_room)
  473.         if(temp_char != ch) {
  474.             if (GET_CLASS(ch) == GET_CLASS(temp_char))
  475.                 act(buf, FALSE, ch, 0, temp_char, TO_VICT);
  476.             else
  477.                 act(buf2, FALSE, ch, 0, temp_char, TO_VICT);
  478.  
  479.         }
  480.  
  481. }
  482.  
  483.  
  484.  
  485. bool saves_spell(struct char_data *ch, sh_int save_type)
  486. {
  487.     int save;
  488.  
  489.     /* Negative apply_saving_throw makes saving throw better! */
  490.  
  491.     save = ch->specials.apply_saving_throw[save_type];
  492.  
  493.     if (!IS_NPC(ch)) {
  494.         save += saving_throws[GET_CLASS(ch)-1][save_type][GET_LEVEL(ch)];
  495.         if (GET_LEVEL(ch) > 20)
  496.             return(TRUE);
  497.     }
  498.  
  499.     return(MAX(1,save) < number(1,20));
  500. }
  501.  
  502.  
  503.  
  504. char *skip_spaces(char *string)
  505. {
  506.     for(;*string && (*string)==' ';string++);
  507.  
  508.     return(string);
  509. }
  510.  
  511.  
  512.  
  513. /* Assumes that *argument does start with first letter of chopped string */
  514.  
  515. void do_cast(struct char_data *ch, char *argument, int cmd)
  516. {
  517.     struct obj_data *tar_obj;
  518.     struct char_data *tar_char;
  519.     char name[MAX_STRING_LENGTH];
  520.     int qend, spl, i;
  521.     bool target_ok;
  522.  
  523.     if (IS_NPC(ch))
  524.         return;
  525.  
  526.     if (GET_LEVEL(ch) < 21) {
  527.         if (GET_CLASS(ch) == CLASS_WARRIOR) {
  528.                 send_to_char("Think you had better stick to fighting...\n\r", ch);
  529.                 return;
  530.         }    else if (GET_CLASS(ch) == CLASS_THIEF) {
  531.                 send_to_char("Think you should stick to robbing and killing...\n\r", ch);
  532.                 return;
  533.         }
  534.     }
  535.  
  536.     argument = skip_spaces(argument);
  537.  
  538.     /* If there is no chars in argument */
  539.     if (!(*argument)) {
  540.         send_to_char("Cast which what where?\n\r", ch);
  541.         return;
  542.     }
  543.  
  544.     if (*argument != '\'') {
  545.         send_to_char("Magic must always be enclosed by the holy magic symbols : '\n\r",ch);
  546.         return;
  547.     }
  548.  
  549.     /* Locate the last quote && lowercase the magic words (if any) */
  550.  
  551.     for (qend=1; *(argument+qend) && (*(argument+qend) != '\'') ; qend++)
  552.         *(argument+qend) = LOWER(*(argument+qend));
  553.  
  554.     if (*(argument+qend) != '\'') {
  555.         send_to_char("Magic must always be enclosed by the holy magic symbols : '\n\r",ch);
  556.         return;
  557.     }
  558.  
  559.     spl = old_search_block(argument, 1, qend-1,spells, 0);
  560.  
  561.     if (!spl) {
  562.         send_to_char("Your lips do not move, no magic appears.\n\r",ch);
  563.         return;
  564.     }
  565.  
  566.     if ((spl > 0) && (spl <= 44) && spell_info[spl].spell_pointer) {
  567.         if (GET_POS(ch) < spell_info[spl].minimum_position) {
  568.             switch(GET_POS(ch)) {
  569.                 case POSITION_SLEEPING :
  570.                     send_to_char("You dream about great magical powers.\n\r", ch);
  571.                     break;
  572.                 case POSITION_RESTING :
  573.                     send_to_char("You can't concentrate enough while resting.\n\r",ch);
  574.                     break;
  575.                 case POSITION_SITTING :
  576.                     send_to_char("You can't do this sitting!\n\r", ch);
  577.                     break;
  578.                 case POSITION_FIGHTING :
  579.                     send_to_char("Impossible! You can't concentrate enough!.\n\r", ch);
  580.                     break;
  581.                 default:
  582.                     send_to_char("It seems like you're in a pretty bad shape!\n\r",ch);
  583.                     break;
  584.             } /* Switch */
  585.         }    else {
  586.  
  587.             if (GET_LEVEL(ch) < 21) {
  588.                 if ((GET_CLASS(ch) == CLASS_MAGIC_USER) &&
  589.                    (spell_info[spl].min_level_magic > GET_LEVEL(ch))) {
  590.                     send_to_char("Sorry, you can't do that.\n\r", ch);
  591.                     return;
  592.                 }
  593.                 if ((GET_CLASS(ch) == CLASS_CLERIC) &&
  594.                    (spell_info[spl].min_level_cleric > GET_LEVEL(ch))) {
  595.                     send_to_char("Sorry, you can't do that.\n\r", ch);
  596.                     return;
  597.                 }
  598.             }
  599.  
  600.             argument+=qend+1;    /* Point to the last ' */
  601.             for(;*argument == ' '; argument++);
  602.  
  603.             /* **************** Locate targets **************** */
  604.  
  605.             target_ok = FALSE;
  606.             tar_char = 0;
  607.             tar_obj = 0;
  608.  
  609.             if (!IS_SET(spell_info[spl].targets, TAR_IGNORE)) {
  610.  
  611.                 argument = one_argument(argument, name);
  612.  
  613.                 if (*name) {
  614.                     if (IS_SET(spell_info[spl].targets, TAR_CHAR_ROOM))
  615.                         if (tar_char = get_char_room_vis(ch, name))
  616.                             target_ok = TRUE;
  617.  
  618.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_CHAR_WORLD))
  619.                         if (tar_char = get_char_vis(ch, name))
  620.                             target_ok = TRUE;
  621.  
  622.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_INV))
  623.                         if (tar_obj = get_obj_in_list_vis(ch, name, ch->carrying))
  624.                             target_ok = TRUE;
  625.  
  626.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_ROOM))
  627.                         if (tar_obj = get_obj_in_list_vis(ch, name, world[ch->in_room].contents))
  628.                             target_ok = TRUE;
  629.  
  630.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
  631.                         if (tar_obj = get_obj_vis(ch, name))
  632.                             target_ok = TRUE;
  633.  
  634.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_OBJ_EQUIP)) {
  635.                         for(i=0; i<MAX_WEAR && !target_ok; i++)
  636.                             if (ch->equipment[i] && str_cmp(name, ch->equipment[i]->name) == 0) {
  637.                                 tar_obj = ch->equipment[i];
  638.                                 target_ok = TRUE;
  639.                             }
  640.                     }
  641.  
  642.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY))
  643.                         if (str_cmp(GET_NAME(ch), name) == 0) {
  644.                             tar_char = ch;
  645.                             target_ok = TRUE;
  646.                         }
  647.  
  648.                 } else { /* No argument was typed */
  649.  
  650.                     if (IS_SET(spell_info[spl].targets, TAR_FIGHT_SELF))
  651.                         if (ch->specials.fighting) {
  652.                             tar_char = ch;
  653.                             target_ok = TRUE;
  654.                         }
  655.  
  656.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_FIGHT_VICT))
  657.                         if (ch->specials.fighting) {
  658.                             /* WARNING, MAKE INTO POINTER */
  659.                             tar_char = ch->specials.fighting;
  660.                             target_ok = TRUE;
  661.                         }
  662.  
  663.                     if (!target_ok && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY)) {
  664.                         tar_char = ch;
  665.                         target_ok = TRUE;
  666.                     }
  667.  
  668.                 }
  669.  
  670.             } else {
  671.                 target_ok = TRUE; /* No target, is a good target */
  672.             }
  673.  
  674.             if (!target_ok) {
  675.                 if (*name) {
  676.                     if (IS_SET(spell_info[spl].targets, TAR_CHAR_ROOM))
  677.                         send_to_char("Nobody here by that name.\n\r", ch);
  678.                     else if (IS_SET(spell_info[spl].targets, TAR_CHAR_WORLD))
  679.                         send_to_char("Nobody playing by that name.\n\r", ch);
  680.                     else if (IS_SET(spell_info[spl].targets, TAR_OBJ_INV))
  681.                         send_to_char("You are not carrying anything like that.\n\r", ch);
  682.                     else if (IS_SET(spell_info[spl].targets, TAR_OBJ_ROOM))
  683.                         send_to_char("Nothing here by that name.\n\r", ch);
  684.                     else if (IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
  685.                         send_to_char("Nothing at all by that name.\n\r", ch);
  686.                     else if (IS_SET(spell_info[spl].targets, TAR_OBJ_EQUIP))
  687.                         send_to_char("You are not wearing anything like that.\n\r", ch);
  688.                     else if (IS_SET(spell_info[spl].targets, TAR_OBJ_WORLD))
  689.                         send_to_char("Nothing at all by that name.\n\r", ch);
  690.  
  691.                 } else { /* Nothing was given as argument */
  692.                     if (spell_info[spl].targets < TAR_OBJ_INV)
  693.                         send_to_char("Who should the spell be cast upon?\n\r", ch);
  694.                     else
  695.                         send_to_char("What should the spell be cast upon?\n\r", ch);
  696.                 }
  697.                 return;
  698.             } else { /* TARGET IS OK */
  699.                 if ((tar_char == ch) && IS_SET(spell_info[spl].targets, TAR_SELF_NONO)) {
  700.                     send_to_char("You can not cast this spell upon yourself.\n\r", ch);
  701.                     return;
  702.                 }
  703.                 else if ((tar_char != ch) && IS_SET(spell_info[spl].targets, TAR_SELF_ONLY)) {
  704.                     send_to_char("You can only cast this spell upon yourself.\n\r", ch);
  705.                     return;
  706.                 } else if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master == tar_char)) {
  707.                     send_to_char("You are afraid that it could harm your master.\n\r", ch);
  708.                     return;
  709.                 }
  710.             }
  711.  
  712.             if (GET_LEVEL(ch) < 21) {
  713.                 if (GET_MANA(ch) < USE_MANA(ch, spl)) {
  714.                     send_to_char("You can't summon enough energy to cast the spell.\n\r", ch);
  715.                     return;
  716.                 }
  717.             }
  718.  
  719.             if (spl != SPELL_VENTRILOQUATE)  /* :-) */
  720.                 say_spell(ch, spl);
  721.  
  722.             WAIT_STATE(ch, spell_info[spl].beats);
  723.  
  724.             if ((spell_info[spl].spell_pointer == 0) && spl>0)
  725.                 send_to_char("Sorry, this magic has not yet been implemented :(\n\r", ch);
  726.             else {
  727.                 if (number(1,101) > ch->skills[spl].learned) { /* 101% is failure */
  728.                     send_to_char("You lost your concentration!\n\r", ch);
  729.                     GET_MANA(ch) -= (USE_MANA(ch, spl)>>1);
  730.                     return;
  731.                 }
  732.                 send_to_char("Ok.\n\r",ch);
  733.                 ((*spell_info[spl].spell_pointer) (GET_LEVEL(ch), ch, argument, SPELL_TYPE_SPELL, tar_char, tar_obj));
  734.                 GET_MANA(ch) -= (USE_MANA(ch, spl));
  735.             }
  736.  
  737.         }    /* if GET_POS < min_pos */
  738.  
  739.         return;
  740.     }
  741.  
  742.     switch (number(1,5)){
  743.         case 1: send_to_char("Bylle Grylle Grop Gryf???\n\r", ch); break;
  744.         case 2: send_to_char("Olle Bolle Snop Snyf?\n\r",ch); break;
  745.         case 3: send_to_char("Olle Grylle Bolle Bylle?!?\n\r",ch); break;
  746.         case 4: send_to_char("Gryffe Olle Gnyffe Snop???\n\r",ch); break;
  747.       default: send_to_char("Bolle Snylle Gryf Bylle?!!?\n\r",ch); break;
  748.     }
  749. }
  750.  
  751.  
  752. void assign_spell_pointers(void)
  753. {
  754.     int i;
  755.  
  756.     for(i=0; i<MAX_SPL_LIST; i++)
  757.         spell_info[i].spell_pointer = 0;
  758.  
  759.  
  760.     /* From spells1.c */
  761.  
  762.     SPELLO(32,12,POSITION_FIGHTING, 1, 21, 15,
  763.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_magic_missile);
  764.  
  765.     SPELLO( 8,12,POSITION_FIGHTING, 3, 21, 15,
  766.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_chill_touch);
  767.  
  768.     SPELLO( 5,12,POSITION_FIGHTING, 5, 21, 15,
  769.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_burning_hands);
  770.  
  771.     SPELLO(37,12,POSITION_FIGHTING, 7, 21, 15,
  772.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_shocking_grasp);
  773.  
  774.     SPELLO(30,12,POSITION_FIGHTING, 9, 21, 15,
  775.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_lightning_bolt);
  776.  
  777.     SPELLO(10,12,POSITION_FIGHTING, 11,21, 15,
  778.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_colour_spray);
  779.  
  780.     SPELLO(25,12,POSITION_FIGHTING, 13,21, 35,
  781.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_energy_drain);
  782.  
  783.     SPELLO(26,12,POSITION_FIGHTING, 15,21, 15,
  784.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_fireball);
  785.  
  786.     SPELLO(23,12,POSITION_FIGHTING, 21, 7, 15,
  787.      TAR_IGNORE, cast_earthquake);
  788.  
  789.     SPELLO(22,12,POSITION_FIGHTING, 21, 10, 15,
  790.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_dispel_evil);
  791.  
  792.     SPELLO( 6,12,POSITION_FIGHTING, 21, 12, 15,
  793.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_call_lightning);
  794.  
  795.     SPELLO(27,12,POSITION_FIGHTING, 21, 15, 35,
  796.      TAR_CHAR_ROOM | TAR_FIGHT_VICT, cast_harm);
  797.  
  798.  
  799.  
  800.     /* Spells2.c */
  801.  
  802.     SPELLO( 1,12,POSITION_STANDING, 5,  1, 5,
  803.      TAR_CHAR_ROOM, cast_armor);
  804.  
  805.     SPELLO( 2,12,POSITION_FIGHTING, 8, 21, 35,
  806.      TAR_SELF_ONLY, cast_teleport);
  807.  
  808.     SPELLO( 3,12,POSITION_STANDING,21,  5, 5,
  809.      TAR_OBJ_INV | TAR_OBJ_EQUIP | TAR_CHAR_ROOM, cast_bless);
  810.  
  811.     SPELLO( 4,12,POSITION_STANDING, 8,  6, 5,
  812.      TAR_CHAR_ROOM, cast_blindness);
  813.  
  814.     SPELLO(7,12,POSITION_STANDING, 14, 21, 5,
  815.      TAR_CHAR_ROOM | TAR_SELF_NONO, cast_charm_person);
  816.  
  817.     SPELLO( 9,12,POSITION_STANDING,15, 21, 40,
  818.      TAR_CHAR_ROOM, cast_clone);
  819.  
  820.     SPELLO(11,12,POSITION_STANDING,10, 13, 25,
  821.      TAR_IGNORE, cast_control_weather);
  822.  
  823.     SPELLO(12,12,POSITION_STANDING,21,  3, 5,
  824.      TAR_IGNORE, cast_create_food);
  825.  
  826.     SPELLO(13,12,POSITION_STANDING,21,  2, 5,
  827.      TAR_OBJ_INV | TAR_OBJ_EQUIP, cast_create_water);
  828.  
  829.     SPELLO(14,12,POSITION_STANDING,21,  4, 5,
  830.      TAR_CHAR_ROOM, cast_cure_blind);
  831.  
  832.     SPELLO(15,12,POSITION_FIGHTING,21,  9, 20,
  833.      TAR_CHAR_ROOM, cast_cure_critic);
  834.  
  835.     SPELLO(16,12,POSITION_FIGHTING,21,  1, 15,
  836.      TAR_CHAR_ROOM, cast_cure_light);
  837.  
  838.     SPELLO(17,12,POSITION_STANDING,12, 21, 20,
  839.      TAR_CHAR_ROOM | TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, cast_curse);
  840.  
  841.     SPELLO(18,12,POSITION_STANDING,21,  4, 5,
  842.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_detect_evil);
  843.  
  844.     SPELLO(19,12,POSITION_STANDING, 2,  5, 5,
  845.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_detect_invisibility);
  846.  
  847.     SPELLO(20,12,POSITION_STANDING, 2,  3, 5,
  848.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_detect_magic);
  849.  
  850.     SPELLO(21,12,POSITION_STANDING,21,  2, 5,
  851.      TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, cast_detect_poison);
  852.  
  853.     SPELLO(24,12,POSITION_STANDING,12, 21, 100,
  854.      TAR_OBJ_INV | TAR_OBJ_EQUIP, cast_enchant_weapon);
  855.  
  856.     SPELLO(28,12,POSITION_FIGHTING,21, 14, 50,
  857.      TAR_CHAR_ROOM, cast_heal);
  858.  
  859.     SPELLO(29,12,POSITION_STANDING, 4, 21, 5,
  860.      TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM | TAR_OBJ_EQUIP, cast_invisibility);
  861.  
  862.     SPELLO(31,12,POSITION_STANDING, 6, 21, 20,
  863.      TAR_OBJ_WORLD, cast_locate_object);
  864.  
  865.     SPELLO(33,12,POSITION_STANDING,21,  8, 10,
  866.      TAR_CHAR_ROOM | TAR_SELF_NONO | TAR_OBJ_INV | TAR_OBJ_EQUIP, cast_poison);
  867.  
  868.     SPELLO(34,12,POSITION_STANDING,21,  6, 5,
  869.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_protection_from_evil);
  870.  
  871.     SPELLO(35,12,POSITION_STANDING,21, 12, 5,
  872.      TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP | TAR_OBJ_ROOM, cast_remove_curse);
  873.  
  874.     SPELLO(36,12,POSITION_STANDING,21, 13, 75,
  875.      TAR_CHAR_ROOM, cast_sanctuary);
  876.  
  877.     SPELLO(38,12,POSITION_STANDING,14, 21, 15,
  878.      TAR_CHAR_ROOM, cast_sleep);
  879.  
  880.     SPELLO(39,12,POSITION_STANDING, 7, 21, 20,
  881.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_strength);
  882.  
  883.     SPELLO(40,12,POSITION_STANDING,21,  8, 50,
  884.      TAR_CHAR_WORLD, cast_summon);
  885.  
  886.     SPELLO(41,12,POSITION_STANDING, 1, 21, 5,
  887.      TAR_CHAR_ROOM | TAR_OBJ_ROOM | TAR_SELF_NONO, cast_ventriloquate);
  888.  
  889.     SPELLO(42,12,POSITION_STANDING,21, 11, 5,
  890.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_word_of_recall);
  891.  
  892.     SPELLO(43,12,POSITION_STANDING,21,  9, 5,
  893.      TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, cast_remove_poison);
  894.  
  895.     SPELLO(44,12,POSITION_STANDING,21,  7, 5,
  896.      TAR_CHAR_ROOM | TAR_SELF_ONLY, cast_sense_life);
  897.  
  898.     SPELLO(45,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  899.     SPELLO(46,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  900.     SPELLO(47,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  901.     SPELLO(48,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  902.     SPELLO(49,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  903.     SPELLO(50,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  904.     SPELLO(51,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  905.     SPELLO(52,0,POSITION_STANDING,25,25,200, TAR_IGNORE, 0);
  906.  
  907.     SPELLO(53,1,POSITION_STANDING,25,25, 100, TAR_IGNORE, cast_identify);
  908.  
  909. }
  910.