MAGIC.C
上传用户:kesirui
上传日期:2007-01-07
资源大小:263k
文件大小:80k
源码类别:

Internet/网络编程

开发平台:

WINDOWS

  1. /***************************************************************************
  2.  *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
  3.  *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
  4.  *                                                                         *
  5.  *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
  6.  *  Chastain, Michael Quan, and Mitchell Tse.                              *
  7.  *                                                                         *
  8.  *  In order to use any part of this Merc Diku Mud, you must comply with   *
  9.  *  both the original Diku license in 'license.doc' as well the Merc       *
  10.  *  license in 'license.txt'.  In particular, you may not remove either of *
  11.  *  these copyright notices.                                               *
  12.  *                                                                         *
  13.  *  Much time and thought has gone into this software and you are          *
  14.  *  benefitting.  We hope that you share your changes too.  What goes      *
  15.  *  around, comes around.                                                  *
  16.  ***************************************************************************/
  17. #if defined(macintosh)
  18. #include <types.h>
  19. #else
  20. #include <sys/types.h>
  21. #endif
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include "merc.h"
  27. /*
  28.  * Local functions.
  29.  */
  30. void say_spell args( ( CHAR_DATA *ch, int sn ) );
  31. /*
  32.  * Lookup a skill by name.
  33.  */
  34. int skill_lookup( const char *name )
  35. {
  36.     int sn;
  37.     for ( sn = 0; sn < MAX_SKILL; sn++ )
  38.     {
  39. if ( skill_table[sn].name == NULL )
  40.     break;
  41. if ( LOWER(name[0]) == LOWER(skill_table[sn].name[0])
  42. &&   !str_prefix( name, skill_table[sn].name ) )
  43.     return sn;
  44.     }
  45.     return -1;
  46. }
  47. /*
  48.  * Lookup a skill by slot number.
  49.  * Used for object loading.
  50.  */
  51. int slot_lookup( int slot )
  52. {
  53.     extern bool fBootDb;
  54.     int sn;
  55.     if ( slot <= 0 )
  56. return -1;
  57.     for ( sn = 0; sn < MAX_SKILL; sn++ )
  58.     {
  59. if ( slot == skill_table[sn].slot )
  60.     return sn;
  61.     }
  62.     if ( fBootDb )
  63.     {
  64. bug( "Slot_lookup: bad slot %d.", slot );
  65. abort( );
  66.     }
  67.     return -1;
  68. }
  69. /*
  70.  * Utter mystical words for an sn.
  71.  */
  72. void say_spell( CHAR_DATA *ch, int sn )
  73. {
  74.     char buf  [MAX_STRING_LENGTH];
  75.     char buf2 [MAX_STRING_LENGTH];
  76.     CHAR_DATA *rch;
  77.     char *pName;
  78.     int iSyl;
  79.     int length;
  80.     struct syl_type
  81.     {
  82. char * old;
  83. char * new;
  84.     };
  85.     static const struct syl_type syl_table[] =
  86.     {
  87. { " ", " " },
  88. { "ar", "abra" },
  89. { "au", "kada" },
  90. { "bless", "fido" },
  91. { "blind", "nose" },
  92. { "bur", "mosa" },
  93. { "cu", "judi" },
  94. { "de", "oculo" },
  95. { "en", "unso" },
  96. { "light", "dies" },
  97. { "lo", "hi" },
  98. { "mor", "zak" },
  99. { "move", "sido" },
  100. { "ness", "lacri" },
  101. { "ning", "illa" },
  102. { "per", "duda" },
  103. { "ra", "gru" },
  104. { "re", "candus" },
  105. { "son", "sabru" },
  106. { "tect", "infra" },
  107. { "tri", "cula" },
  108. { "ven", "nofo" },
  109. { "a", "a" }, { "b", "b" }, { "c", "q" }, { "d", "e" },
  110. { "e", "z" }, { "f", "y" }, { "g", "o" }, { "h", "p" },
  111. { "i", "u" }, { "j", "y" }, { "k", "t" }, { "l", "r" },
  112. { "m", "w" }, { "n", "i" }, { "o", "a" }, { "p", "s" },
  113. { "q", "d" }, { "r", "f" }, { "s", "g" }, { "t", "h" },
  114. { "u", "j" }, { "v", "z" }, { "w", "x" }, { "x", "n" },
  115. { "y", "l" }, { "z", "k" },
  116. { "", "" }
  117.     };
  118.     buf[0] = '';
  119.     for ( pName = skill_table[sn].name; *pName != ''; pName += length )
  120.     {
  121. for ( iSyl = 0; (length = strlen(syl_table[iSyl].old)) != 0; iSyl++ )
  122. {
  123.     if ( !str_prefix( syl_table[iSyl].old, pName ) )
  124.     {
  125. strcat( buf, syl_table[iSyl].new );
  126. break;
  127.     }
  128. }
  129. if ( length == 0 )
  130.     length = 1;
  131.     }
  132.     sprintf( buf2, "$n utters the words, '%s'.", buf );
  133.     sprintf( buf,  "$n utters the words, '%s'.", skill_table[sn].name );
  134.     for ( rch = ch->in_room->people; rch; rch = rch->next_in_room )
  135.     {
  136. if ( rch != ch )
  137.     act( ch->class==rch->class ? buf : buf2, ch, NULL, rch, TO_VICT );
  138.     }
  139.     return;
  140. }
  141. /*
  142.  * Compute a saving throw.
  143.  * Negative apply's make saving throw better.
  144.  */
  145. bool saves_spell( int level, CHAR_DATA *victim )
  146. {
  147.     int save;
  148.     save = 50 + ( victim->level - level - victim->saving_throw ) * 5;
  149.     save = URANGE( 5, save, 95 );
  150.     return number_percent( ) < save;
  151. }
  152. /*
  153.  * The kludgy global is for spells who want more stuff from command line.
  154.  */
  155. char *target_name;
  156. void do_cast( CHAR_DATA *ch, char *argument )
  157. {
  158.     char arg1[MAX_INPUT_LENGTH];
  159.     char arg2[MAX_INPUT_LENGTH];
  160.     CHAR_DATA *victim;
  161.     OBJ_DATA *obj;
  162.     void *vo;
  163.     int mana;
  164.     int sn;
  165.     /*
  166.      * Only MOBprogrammed mobs not charmed can cast spells
  167.      * like PC's
  168.      */
  169.     if ( IS_NPC(ch)
  170. && ( !ch->pIndexData->progtypes
  171.     || IS_AFFECTED( ch, AFF_CHARM ) ) )
  172. return;
  173.     target_name = one_argument( argument, arg1 );
  174.     one_argument( target_name, arg2 );
  175.     if ( arg1[0] == '' )
  176.     {
  177. send_to_char( "Cast which what where?nr", ch );
  178. return;
  179.     }
  180.     if ( ( sn = skill_lookup( arg1 ) ) < 0
  181.     || ( !IS_NPC(ch) && ch->level < skill_table[sn].skill_level[ch->class] ) )
  182.     {
  183. send_to_char( "You can't do that.nr", ch );
  184. return;
  185.     }
  186.   
  187.     if ( ch->position < skill_table[sn].minimum_position )
  188.     {
  189. send_to_char( "You can't concentrate enough.nr", ch );
  190. return;
  191.     }
  192.     mana = MANA_COST(ch, sn);
  193.     /*
  194.      * Locate targets.
  195.      */
  196.     victim = NULL;
  197.     obj = NULL;
  198.     vo = NULL;
  199.       
  200.     switch ( skill_table[sn].target )
  201.     {
  202.     default:
  203. bug( "Do_cast: bad target for sn %d.", sn );
  204. return;
  205.     case TAR_IGNORE:
  206. break;
  207.     case TAR_CHAR_OFFENSIVE:
  208. if ( arg2[0] == '' )
  209. {
  210.     if ( ( victim = ch->fighting ) == NULL )
  211.     {
  212. send_to_char( "Cast the spell on whom?nr", ch );
  213. return;
  214.     }
  215. }
  216. else
  217. {
  218.     if ( ( victim = get_char_room( ch, arg2 ) ) == NULL )
  219.     {
  220. send_to_char( "They aren't here.nr", ch );
  221. return;
  222.     }
  223. }
  224. /* if ( !IS_NPC(ch) )
  225. {
  226.     if ( !IS_NPC(victim) && ch != victim )
  227.     {
  228. send_to_char( "You can't do that on a player.nr", ch );
  229. return;
  230.     }
  231.     if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim )
  232.     {
  233. send_to_char( "You can't do that on your own follower.nr",
  234.     ch );
  235. return;
  236.     }
  237. }
  238. */
  239. vo = (void *) victim;
  240. break;
  241.     case TAR_CHAR_DEFENSIVE:
  242. if ( arg2[0] == '' )
  243. {
  244.     victim = ch;
  245. }
  246. else
  247. {
  248.     if ( ( victim = get_char_room( ch, arg2 ) ) == NULL )
  249.     {
  250. send_to_char( "They aren't here.nr", ch );
  251. return;
  252.     }
  253. }
  254. vo = (void *) victim;
  255. break;
  256.     case TAR_CHAR_SELF:
  257. if ( arg2[0] != '' && !is_name( arg2, ch->name ) )
  258. {
  259.     send_to_char( "You cannot cast this spell on another.nr", ch );
  260.     return;
  261. }
  262. vo = (void *) ch;
  263. break;
  264.     case TAR_OBJ_INV:
  265. if ( arg2[0] == '' )
  266. {
  267.     send_to_char( "What should the spell be cast upon?nr", ch );
  268.     return;
  269. }
  270. if ( ( obj = get_obj_carry( ch, arg2 ) ) == NULL )
  271. {
  272.     send_to_char( "You are not carrying that.nr", ch );
  273.     return;
  274. }
  275. vo = (void *) obj;
  276. break;
  277.     }
  278.     
  279.     if ( !IS_NPC(ch) && ch->mana < mana )
  280.     {
  281. send_to_char( "You don't have enough mana.nr", ch );
  282. return;
  283.     }
  284.       
  285.     if ( str_cmp( skill_table[sn].name, "ventriloquate" ) )
  286. say_spell( ch, sn );
  287.       
  288.     WAIT_STATE( ch, skill_table[sn].beats );
  289.       
  290.     if ( !IS_NPC(ch) && number_percent( ) > ch->pcdata->learned[sn] )
  291.     {
  292. send_to_char( "You lost your concentration.nr", ch );
  293. ch->mana -= mana / 2;
  294.     }
  295.     else
  296.     {
  297. ch->mana -= mana;
  298. (*skill_table[sn].spell_fun) ( sn, ch->level, ch, vo );
  299.     }
  300.     if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE
  301. && victim->master != ch && victim != ch )
  302.     {
  303. CHAR_DATA *vch;
  304. CHAR_DATA *vch_next;
  305. for ( vch = ch->in_room->people; vch; vch = vch_next )
  306. {
  307.     vch_next = vch->next_in_room;
  308.     if ( victim == vch && victim->fighting == NULL )
  309.     {
  310. multi_hit( victim, ch, TYPE_UNDEFINED );
  311. break;
  312.     }
  313. }
  314.     }
  315.     return;
  316. }
  317. /*
  318.  * Cast spells at targets using a magical object.
  319.  */
  320. void obj_cast_spell( int sn, int level, CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj )
  321. {
  322.     void *vo;
  323.     if ( sn <= 0 )
  324. return;
  325.     if ( sn >= MAX_SKILL || skill_table[sn].spell_fun == 0 )
  326.     {
  327. bug( "Obj_cast_spell: bad sn %d.", sn );
  328. return;
  329.     }
  330.     switch ( skill_table[sn].target )
  331.     {
  332.     default:
  333. bug( "Obj_cast_spell: bad target for sn %d.", sn );
  334. return;
  335.     case TAR_IGNORE:
  336. vo = NULL;
  337. break;
  338.     case TAR_CHAR_OFFENSIVE:
  339. if ( victim == NULL )
  340.     victim = ch->fighting;
  341. if ( victim == NULL || !IS_NPC(victim) )
  342. {
  343.     send_to_char( "You can't do that.nr", ch );
  344.     return;
  345. }
  346. vo = (void *) victim;
  347. break;
  348.     case TAR_CHAR_DEFENSIVE:
  349. if ( victim == NULL )
  350.     victim = ch;
  351. vo = (void *) victim;
  352. break;
  353.     case TAR_CHAR_SELF:
  354. vo = (void *) ch;
  355. break;
  356.     case TAR_OBJ_INV:
  357. if ( obj == NULL )
  358. {
  359.     send_to_char( "You can't do that.nr", ch );
  360.     return;
  361. }
  362. vo = (void *) obj;
  363. break;
  364.     }
  365.     target_name = "";
  366.     (*skill_table[sn].spell_fun) ( sn, level, ch, vo );
  367.     if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim->master != ch )
  368.     {
  369. CHAR_DATA *vch;
  370. CHAR_DATA *vch_next;
  371. for ( vch = ch->in_room->people; vch; vch = vch_next )
  372. {
  373.     vch_next = vch->next_in_room;
  374.     if ( victim == vch && victim->fighting == NULL )
  375.     {
  376. multi_hit( victim, ch, TYPE_UNDEFINED );
  377. break;
  378.     }
  379. }
  380.     }
  381.     return;
  382. }
  383. /*
  384.  * Spell functions.
  385.  */
  386. void spell_acid_blast( int sn, int level, CHAR_DATA *ch, void *vo )
  387. {
  388.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  389.     int dam;
  390.     dam = dice( level, 6 );
  391.     if ( saves_spell( level, victim ) )
  392. dam /= 2;
  393.     damage( ch, victim, dam, sn );
  394.     return;
  395. }
  396. void spell_armor( int sn, int level, CHAR_DATA *ch, void *vo )
  397. {
  398.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  399.     AFFECT_DATA af;
  400.     if ( is_affected( victim, sn ) )
  401. return;
  402.     af.type      = sn;
  403.     af.duration  = 24;
  404.     af.modifier  = -20;
  405.     af.location  = APPLY_AC;
  406.     af.bitvector = 0;
  407.     affect_to_char( victim, &af );
  408.     send_to_char( "You feel someone protecting you.nr", victim );
  409.     if ( ch != victim )
  410. send_to_char( "Ok.nr", ch );
  411.     return;
  412. }
  413. void spell_bless( int sn, int level, CHAR_DATA *ch, void *vo )
  414. {
  415.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  416.     AFFECT_DATA af;
  417.     if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
  418. return;
  419.     af.type      = sn;
  420.     af.duration  = 6+level;
  421.     af.location  = APPLY_HITROLL;
  422.     af.modifier  = level / 8;
  423.     af.bitvector = 0;
  424.     affect_to_char( victim, &af );
  425.     af.location  = APPLY_SAVING_SPELL;
  426.     af.modifier  = 0 - level / 8;
  427.     affect_to_char( victim, &af );
  428.     send_to_char( "You feel righteous.nr", victim );
  429.     if ( ch != victim )
  430. send_to_char( "Ok.nr", ch );
  431.     return;
  432. }
  433. void spell_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
  434. {
  435.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  436.     AFFECT_DATA af;
  437.     if ( IS_AFFECTED(victim, AFF_BLIND) || saves_spell( level, victim ) )
  438. return;
  439.     af.type      = sn;
  440.     af.location  = APPLY_HITROLL;
  441.     af.modifier  = -4;
  442.     af.duration  = 1+level;
  443.     af.bitvector = AFF_BLIND;
  444.     affect_to_char( victim, &af );
  445.     send_to_char( "You are blinded!nr", victim );
  446.     if ( ch != victim )
  447. send_to_char( "Ok.nr", ch );
  448.     return;
  449. }
  450. void spell_burning_hands( int sn, int level, CHAR_DATA *ch, void *vo )
  451. {
  452.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  453.     static const sh_int dam_each[] = 
  454.     {
  455.  0,
  456.  0,  0,  0,  0, 14, 17, 20, 23, 26, 29,
  457. 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
  458. 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
  459. 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
  460. 44, 44, 45, 45, 46, 46, 47, 47, 48, 48
  461.     };
  462.     int dam;
  463.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  464.     level = UMAX(0, level);
  465.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  466.     if ( saves_spell( level, victim ) )
  467. dam /= 2;
  468.     damage( ch, victim, dam, sn );
  469.     return;
  470. }
  471. void spell_call_lightning( int sn, int level, CHAR_DATA *ch, void *vo )
  472. {
  473.     CHAR_DATA *vch;
  474.     CHAR_DATA *vch_next;
  475.     int dam;
  476.     if ( !IS_OUTSIDE(ch) )
  477.     {
  478. send_to_char( "You must be out of doors.nr", ch );
  479. return;
  480.     }
  481.     if ( weather_info.sky < SKY_RAINING )
  482.     {
  483. send_to_char( "You need bad weather.nr", ch );
  484. return;
  485.     }
  486.     dam = dice(level/2, 8);
  487.     send_to_char( "God's lightning strikes your foes!nr", ch );
  488.     act( "$n calls God's lightning to strike $s foes!",
  489. ch, NULL, NULL, TO_ROOM );
  490.     for ( vch = char_list; vch != NULL; vch = vch_next )
  491.     {
  492. vch_next = vch->next;
  493. if ( vch->in_room == NULL )
  494.     continue;
  495. if ( vch->in_room == ch->in_room )
  496. {
  497.     if ( vch != ch && ( IS_NPC(ch) ? !IS_NPC(vch) : IS_NPC(vch) ) )
  498. damage( ch, vch, saves_spell( level, vch ) ? dam/2 : dam, sn );
  499.     continue;
  500. }
  501. if ( vch->in_room->area == ch->in_room->area
  502. &&   IS_OUTSIDE(vch)
  503. &&   IS_AWAKE(vch) )
  504.     send_to_char( "Lightning flashes in the sky.nr", vch );
  505.     }
  506.     return;
  507. }
  508. void spell_cause_light( int sn, int level, CHAR_DATA *ch, void *vo )
  509. {
  510.     damage( ch, (CHAR_DATA *) vo, dice(1, 8) + level / 3, sn );
  511.     return;
  512. }
  513. void spell_cause_critical( int sn, int level, CHAR_DATA *ch, void *vo )
  514. {
  515.     damage( ch, (CHAR_DATA *) vo, dice(3, 8) + level - 6, sn );
  516.     return;
  517. }
  518. void spell_cause_serious( int sn, int level, CHAR_DATA *ch, void *vo )
  519. {
  520.     damage( ch, (CHAR_DATA *) vo, dice(2, 8) + level / 2, sn );
  521.     return;
  522. }
  523. void spell_change_sex( int sn, int level, CHAR_DATA *ch, void *vo )
  524. {
  525.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  526.     AFFECT_DATA af;
  527.     if ( is_affected( victim, sn ) )
  528. return;
  529.     af.type      = sn;
  530.     af.duration  = 10 * level;
  531.     af.location  = APPLY_SEX;
  532.     do
  533.     {
  534. af.modifier  = number_range( 0, 2 ) - victim->sex;
  535.     }
  536.     while ( af.modifier == 0 );
  537.     af.bitvector = 0;
  538.     affect_to_char( victim, &af );
  539.     send_to_char( "You feel different.nr", victim );
  540.     if ( ch != victim )
  541. send_to_char( "Ok.nr", ch );
  542.     return;
  543. }
  544. void spell_charm_person( int sn, int level, CHAR_DATA *ch, void *vo )
  545. {
  546.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  547.     AFFECT_DATA af;
  548.     if ( victim == ch )
  549.     {
  550. send_to_char( "You like yourself even better!nr", ch );
  551. return;
  552.     }
  553.     if ( IS_AFFECTED(victim, AFF_CHARM)
  554.     ||   IS_AFFECTED(ch, AFF_CHARM)
  555.     ||   level < victim->level
  556.     ||   saves_spell( level, victim ) )
  557. return;
  558.     if ( victim->master )
  559. stop_follower( victim );
  560.     add_follower( victim, ch );
  561.     af.type      = sn;
  562.     af.duration  = number_fuzzy( level / 4 );
  563.     af.location  = 0;
  564.     af.modifier  = 0;
  565.     af.bitvector = AFF_CHARM;
  566.     affect_to_char( victim, &af );
  567.     act( "Isn't $n just so nice?", ch, NULL, victim, TO_VICT );
  568.     if ( ch != victim )
  569. send_to_char( "Ok.nr", ch );
  570.     return;
  571. }
  572. void spell_chill_touch( int sn, int level, CHAR_DATA *ch, void *vo )
  573. {
  574.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  575.     static const sh_int dam_each[] = 
  576.     {
  577.  0,
  578.  0,  0,  6,  7,  8,  9, 12, 13, 13, 13,
  579. 14, 14, 14, 15, 15, 15, 16, 16, 16, 17,
  580. 17, 17, 18, 18, 18, 19, 19, 19, 20, 20,
  581. 20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
  582. 24, 24, 24, 25, 25, 25, 26, 26, 26, 27
  583.     };
  584.     AFFECT_DATA af;
  585.     int dam;
  586.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  587.     level = UMAX(0, level);
  588.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  589.     if ( !saves_spell( level, victim ) )
  590.     {
  591. af.type      = sn;
  592. af.duration  = 6;
  593. af.location  = APPLY_STR;
  594. af.modifier  = -1;
  595. af.bitvector = 0;
  596. affect_join( victim, &af );
  597.     }
  598.     else
  599.     {
  600. dam /= 2;
  601.     }
  602.     damage( ch, victim, dam, sn );
  603.     return;
  604. }
  605. void spell_colour_spray( int sn, int level, CHAR_DATA *ch, void *vo )
  606. {
  607.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  608.     static const sh_int dam_each[] = 
  609.     {
  610.  0,
  611.  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  612. 30, 35, 40, 45, 50, 55, 55, 55, 56, 57,
  613. 58, 58, 59, 60, 61, 61, 62, 63, 64, 64,
  614. 65, 66, 67, 67, 68, 69, 70, 70, 71, 72,
  615. 73, 73, 74, 75, 76, 76, 77, 78, 79, 79
  616.     };
  617.     int dam;
  618.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  619.     level = UMAX(0, level);
  620.     dam = number_range( dam_each[level] / 2,  dam_each[level] * 2 );
  621.     if ( saves_spell( level, victim ) )
  622. dam /= 2;
  623.     damage( ch, victim, dam, sn );
  624.     return;
  625. }
  626. void spell_continual_light( int sn, int level, CHAR_DATA *ch, void *vo )
  627. {
  628.     OBJ_DATA *light;
  629.     light = create_object( get_obj_index( OBJ_VNUM_LIGHT_BALL ), 0 );
  630.     obj_to_room( light, ch->in_room );
  631.     act( "$n twiddles $s thumbs and $p appears.",   ch, light, NULL, TO_ROOM );
  632.     act( "You twiddle your thumbs and $p appears.", ch, light, NULL, TO_CHAR );
  633.     return;
  634. }
  635. void spell_control_weather( int sn, int level, CHAR_DATA *ch, void *vo )
  636. {
  637.     if ( !str_cmp( target_name, "better" ) )
  638. weather_info.change += dice( level / 3, 4 );
  639.     else if ( !str_cmp( target_name, "worse" ) )
  640. weather_info.change -= dice( level / 3, 4 );
  641.     else
  642. send_to_char ("Do you want it to get better or worse?nr", ch );
  643.     send_to_char( "Ok.nr", ch );
  644.     return;
  645. }
  646. void spell_create_food( int sn, int level, CHAR_DATA *ch, void *vo )
  647. {
  648.     OBJ_DATA *mushroom;
  649.     mushroom = create_object( get_obj_index( OBJ_VNUM_MUSHROOM ), 0 );
  650.     mushroom->value[0] = 5 + level;
  651.     obj_to_room( mushroom, ch->in_room );
  652.     act( "$p suddenly appears.", ch, mushroom, NULL, TO_ROOM );
  653.     act( "$p suddenly appears.", ch, mushroom, NULL, TO_CHAR );
  654.     return;
  655. }
  656. void spell_create_spring( int sn, int level, CHAR_DATA *ch, void *vo )
  657. {
  658.     OBJ_DATA *spring;
  659.     spring = create_object( get_obj_index( OBJ_VNUM_SPRING ), 0 );
  660.     spring->timer = level;
  661.     obj_to_room( spring, ch->in_room );
  662.     act( "$p flows from the ground.", ch, spring, NULL, TO_ROOM );
  663.     act( "$p flows from the ground.", ch, spring, NULL, TO_CHAR );
  664.     return;
  665. }
  666. void spell_create_water( int sn, int level, CHAR_DATA *ch, void *vo )
  667. {
  668.     OBJ_DATA *obj = (OBJ_DATA *) vo;
  669.     int water;
  670.     if ( obj->item_type != ITEM_DRINK_CON )
  671.     {
  672. send_to_char( "It is unable to hold water.nr", ch );
  673. return;
  674.     }
  675.     if ( obj->value[2] != LIQ_WATER && obj->value[1] != 0 )
  676.     {
  677. send_to_char( "It contains some other liquid.nr", ch );
  678. return;
  679.     }
  680.     water = UMIN(
  681. level * (weather_info.sky >= SKY_RAINING ? 4 : 2),
  682. obj->value[0] - obj->value[1]
  683. );
  684.   
  685.     if ( water > 0 )
  686.     {
  687. obj->value[2] = LIQ_WATER;
  688. obj->value[1] += water;
  689. if ( !is_name( "water", obj->name ) )
  690. {
  691.     char buf[MAX_STRING_LENGTH];
  692.     sprintf( buf, "%s water", obj->name );
  693.     free_string( obj->name );
  694.     obj->name = str_dup( buf );
  695. }
  696. act( "$p is filled.", ch, obj, NULL, TO_CHAR );
  697.     }
  698.     return;
  699. }
  700. void spell_cure_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
  701. {
  702.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  703.     if ( !is_affected( victim, gsn_blindness ) )
  704. return;
  705.     affect_strip( victim, gsn_blindness );
  706.     send_to_char( "Your vision returns!nr", victim );
  707.     if ( ch != victim )
  708. send_to_char( "Ok.nr", ch );
  709.     return;
  710. }
  711. void spell_cure_critical( int sn, int level, CHAR_DATA *ch, void *vo )
  712. {
  713.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  714.     int heal;
  715.     heal = dice(3, 8) + level - 6;
  716.     victim->hit = UMIN( victim->hit + heal, victim->max_hit );
  717.     update_pos( victim );
  718.     send_to_char( "You feel better!nr", victim );
  719.     if ( ch != victim )
  720. send_to_char( "Ok.nr", ch );
  721.     return;
  722. }
  723. void spell_cure_light( int sn, int level, CHAR_DATA *ch, void *vo )
  724. {
  725.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  726.     int heal;
  727.     heal = dice(1, 8) + level / 3;
  728.     victim->hit = UMIN( victim->hit + heal, victim->max_hit );
  729.     update_pos( victim );
  730.     send_to_char( "You feel better!nr", victim );
  731.     if ( ch != victim )
  732. send_to_char( "Ok.nr", ch );
  733.     return;
  734. }
  735. void spell_cure_poison( int sn, int level, CHAR_DATA *ch, void *vo )
  736. {
  737.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  738.     if ( is_affected( victim, gsn_poison ) )
  739.     {
  740. affect_strip( victim, gsn_poison );
  741. act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );
  742. send_to_char( "A warm feeling runs through your body.nr", victim );
  743. send_to_char( "Ok.nr", ch );
  744.     }
  745.     return;
  746. }
  747. void spell_cure_serious( int sn, int level, CHAR_DATA *ch, void *vo )
  748. {
  749.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  750.     int heal;
  751.     heal = dice(2, 8) + level /2 ;
  752.     victim->hit = UMIN( victim->hit + heal, victim->max_hit );
  753.     update_pos( victim );
  754.     send_to_char( "You feel better!nr", victim );
  755.     if ( ch != victim )
  756. send_to_char( "Ok.nr", ch );
  757.     return;
  758. }
  759. void spell_curse( int sn, int level, CHAR_DATA *ch, void *vo )
  760. {
  761.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  762.     AFFECT_DATA af;
  763.     if ( IS_AFFECTED(victim, AFF_CURSE) || saves_spell( level, victim ) )
  764. return;
  765.     af.type      = sn;
  766.     af.duration  = 4*level;
  767.     af.location  = APPLY_HITROLL;
  768.     af.modifier  = -1;
  769.     af.bitvector = AFF_CURSE;
  770.     affect_to_char( victim, &af );
  771.     af.location  = APPLY_SAVING_SPELL;
  772.     af.modifier  = 1;
  773.     affect_to_char( victim, &af );
  774.     send_to_char( "You feel unclean.nr", victim );
  775.     if ( ch != victim )
  776. send_to_char( "Ok.nr", ch );
  777.     return;
  778. }
  779. void spell_detect_evil( int sn, int level, CHAR_DATA *ch, void *vo )
  780. {
  781.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  782.     AFFECT_DATA af;
  783.     if ( IS_AFFECTED(victim, AFF_DETECT_EVIL) )
  784. return;
  785.     af.type      = sn;
  786.     af.duration  = level;
  787.     af.modifier  = 0;
  788.     af.location  = APPLY_NONE;
  789.     af.bitvector = AFF_DETECT_EVIL;
  790.     affect_to_char( victim, &af );
  791.     send_to_char( "Your eyes tingle.nr", victim );
  792.     if ( ch != victim )
  793. send_to_char( "Ok.nr", ch );
  794.     return;
  795. }
  796. void spell_detect_hidden( int sn, int level, CHAR_DATA *ch, void *vo )
  797. {
  798.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  799.     AFFECT_DATA af;
  800.     if ( IS_AFFECTED(victim, AFF_DETECT_HIDDEN) )
  801. return;
  802.     af.type      = sn;
  803.     af.duration  = level;
  804.     af.location  = APPLY_NONE;
  805.     af.modifier  = 0;
  806.     af.bitvector = AFF_DETECT_HIDDEN;
  807.     affect_to_char( victim, &af );
  808.     send_to_char( "Your awareness improves.nr", victim );
  809.     if ( ch != victim )
  810. send_to_char( "Ok.nr", ch );
  811.     return;
  812. }
  813. void spell_detect_invis( int sn, int level, CHAR_DATA *ch, void *vo )
  814. {
  815.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  816.     AFFECT_DATA af;
  817.     if ( IS_AFFECTED(victim, AFF_DETECT_INVIS) )
  818. return;
  819.     af.type      = sn;
  820.     af.duration  = level;
  821.     af.modifier  = 0;
  822.     af.location  = APPLY_NONE;
  823.     af.bitvector = AFF_DETECT_INVIS;
  824.     affect_to_char( victim, &af );
  825.     send_to_char( "Your eyes tingle.nr", victim );
  826.     if ( ch != victim )
  827. send_to_char( "Ok.nr", ch );
  828.     return;
  829. }
  830. void spell_detect_magic( int sn, int level, CHAR_DATA *ch, void *vo )
  831. {
  832.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  833.     AFFECT_DATA af;
  834.     if ( IS_AFFECTED(victim, AFF_DETECT_MAGIC) )
  835. return;
  836.     af.type      = sn;
  837.     af.duration  = level;
  838.     af.modifier  = 0;
  839.     af.location  = APPLY_NONE;
  840.     af.bitvector = AFF_DETECT_MAGIC;
  841.     affect_to_char( victim, &af );
  842.     send_to_char( "Your eyes tingle.nr", victim );
  843.     if ( ch != victim )
  844. send_to_char( "Ok.nr", ch );
  845.     return;
  846. }
  847. void spell_detect_poison( int sn, int level, CHAR_DATA *ch, void *vo )
  848. {
  849.     OBJ_DATA *obj = (OBJ_DATA *) vo;
  850.     if ( obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD )
  851.     {
  852. if ( obj->value[3] != 0 )
  853.     send_to_char( "You smell poisonous fumes.nr", ch );
  854. else
  855.     send_to_char( "It looks very delicious.nr", ch );
  856.     }
  857.     else
  858.     {
  859. send_to_char( "It doesn't look poisoned.nr", ch );
  860.     }
  861.     return;
  862. }
  863. void spell_dispel_magic( int sn, int level, CHAR_DATA *ch, void *vo )
  864. {
  865.     send_to_char( "Sorry but this spell has been disabled.nr", ch );
  866.     return;
  867. }
  868. void spell_dispel_evil( int sn, int level, CHAR_DATA *ch, void *vo )
  869. {
  870.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  871.     int dam;
  872.   
  873.     if ( !IS_NPC(ch) && IS_EVIL(ch) )
  874. victim = ch;
  875.   
  876.     if ( IS_GOOD(victim) )
  877.     {
  878. act( "God protects $N.", ch, NULL, victim, TO_ROOM );
  879. return;
  880.     }
  881.     if ( IS_NEUTRAL(victim) )
  882.     {
  883. act( "$N does not seem to be affected.", ch, NULL, victim, TO_CHAR );
  884. return;
  885.     }
  886.     dam = dice( level, 4 );
  887.     if ( saves_spell( level, victim ) )
  888. dam /= 2;
  889.     damage( ch, victim, dam, sn );
  890.     return;
  891. }
  892. void spell_earthquake( int sn, int level, CHAR_DATA *ch, void *vo )
  893. {
  894.     CHAR_DATA *vch;
  895.     CHAR_DATA *vch_next;
  896.     send_to_char( "The earth trembles beneath your feet!nr", ch );
  897.     act( "$n makes the earth tremble and shiver.", ch, NULL, NULL, TO_ROOM );
  898.     for ( vch = char_list; vch != NULL; vch = vch_next )
  899.     {
  900. vch_next = vch->next;
  901. if ( vch->in_room == NULL )
  902.     continue;
  903. if ( vch->in_room == ch->in_room )
  904. {
  905.     if ( vch != ch && ( IS_NPC(ch) ? !IS_NPC(vch) : IS_NPC(vch) ) )
  906. damage( ch, vch, level + dice(2, 8), sn );
  907.     continue;
  908. }
  909. if ( vch->in_room->area == ch->in_room->area )
  910.     send_to_char( "The earth trembles and shivers.nr", vch );
  911.     }
  912.     return;
  913. }
  914. void spell_enchant_weapon( int sn, int level, CHAR_DATA *ch, void *vo )
  915. {
  916.     OBJ_DATA *obj = (OBJ_DATA *) vo;
  917.     AFFECT_DATA *paf;
  918.     if ( obj->item_type != ITEM_WEAPON
  919.     ||   IS_OBJ_STAT(obj, ITEM_MAGIC)
  920.     ||   obj->affected != NULL )
  921. return;
  922.     if ( affect_free == NULL )
  923.     {
  924. paf = alloc_perm( sizeof(*paf) );
  925.     }
  926.     else
  927.     {
  928. paf = affect_free;
  929. affect_free = affect_free->next;
  930.     }
  931.     paf->type = sn;
  932.     paf->duration = -1;
  933.     paf->location = APPLY_HITROLL;
  934.     paf->modifier = level / 5;
  935.     paf->bitvector = 0;
  936.     paf->next = obj->affected;
  937.     obj->affected = paf;
  938.     if ( affect_free == NULL )
  939.     {
  940. paf = alloc_perm( sizeof(*paf) );
  941.     }
  942.     else
  943.     {
  944. paf = affect_free;
  945. affect_free = affect_free->next;
  946.     }
  947.     paf->type = -1;
  948.     paf->duration = -1;
  949.     paf->location = APPLY_DAMROLL;
  950.     paf->modifier = level / 10;
  951.     paf->bitvector = 0;
  952.     paf->next = obj->affected;
  953.     obj->affected = paf;
  954.     obj->level = number_fuzzy( ch->level - 5 );
  955.     if ( IS_GOOD(ch) )
  956.     {
  957. SET_BIT(obj->extra_flags, ITEM_ANTI_EVIL);
  958. act( "$p glows blue.", ch, obj, NULL, TO_CHAR );
  959.     }
  960.     else if ( IS_EVIL(ch) )
  961.     {
  962. SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD);
  963. act( "$p glows red.", ch, obj, NULL, TO_CHAR );
  964.     }
  965.     else
  966.     {
  967. SET_BIT(obj->extra_flags, ITEM_ANTI_EVIL);
  968. SET_BIT(obj->extra_flags, ITEM_ANTI_GOOD);
  969. act( "$p glows yellow.", ch, obj, NULL, TO_CHAR );
  970.     }
  971.     send_to_char( "Ok.nr", ch );
  972.     return;
  973. }
  974. /* "make purse", { 37, 37, 37, 37 },
  975. spell_make_purse, TAR_OBJ_INV, POS_STANDING,
  976. NULL, SLOT(50), 100, 24,
  977. "", "!Make Purse!"*/
  978. void spell_make_purse( int sn, int level, CHAR_DATA *ch, void *vo )
  979. {
  980.     static char *headers[] = { "corpse of the ", "corpse of The ",
  981.                                "corpse of an ", "corpse of An ",
  982.                                "corpse of a ", "corpse of A ",
  983.                                "corpse of " }; // (This one must be last)
  984.     OBJ_DATA *obj = (OBJ_DATA *) vo;
  985.     char buf[MAX_STRING_LENGTH];
  986.     int i;
  987.     if ( obj->item_type != ITEM_CORPSE_NPC && obj->item_type != ITEM_CORPSE_PC)
  988. return;
  989.     for (i = 0; i < 7; i++)
  990.        {
  991.        int len = strlen(headers[i]);
  992.        if ( memcmp(obj->short_descr, headers[i], len) == 0 )
  993.           {
  994.           sprintf( buf, "purse %s", obj->short_descr+len );
  995.           free_string( obj->name );
  996.           obj->name = str_dup(buf);
  997.           sprintf( buf, "A purse of fine %s hide catches your eye.  ",
  998.              obj->short_descr+len );
  999.           free_string( obj->description );
  1000.           obj->description = str_dup( buf );
  1001.           sprintf( buf, "purse made from %s hide", obj->short_descr+len );
  1002.           free_string( obj->short_descr );
  1003.           obj->short_descr = str_dup( buf );
  1004.           break;
  1005.           }
  1006.        }
  1007.     obj->item_type = ITEM_CONTAINER;
  1008.     obj->wear_flags = ITEM_HOLD|ITEM_TAKE;
  1009.     obj->timer = 0;
  1010.     obj->weight = 5;
  1011.     obj->level = level/3;
  1012.     obj->cost = level * 50;
  1013.     obj->value[0] = level * 10;                 /* Weight capacity */
  1014.     obj->value[1] = 1;                          /* Closeable */
  1015.     obj->value[2] = -1;                         /* No key needed */
  1016.     obj->pIndexData = get_obj_index( 5660 );    /* So it's not a corpse */
  1017.     act( "Your new $p looks pretty snazzy.", ch, obj, NULL, TO_CHAR );
  1018.     act( "$n's new $p looks pretty snazzy.", ch, obj, NULL, TO_ROOM );
  1019.     send_to_char( "Ok.nr", ch );
  1020.     return;
  1021. }
  1022. /*
  1023.  * Drain XP, MANA, HP.
  1024.  * Caster gains HP.
  1025.  */
  1026. void spell_energy_drain( int sn, int level, CHAR_DATA *ch, void *vo )
  1027. {
  1028.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1029.     int dam;
  1030.     if ( saves_spell( level, victim ) )
  1031. return;
  1032.     ch->alignment = UMAX(-1000, ch->alignment - 200);
  1033.     if ( victim->level <= 2 )
  1034.     {
  1035. dam  = ch->hit + 1;
  1036.     }
  1037.     else
  1038.     {
  1039. gain_exp( victim, 0 - number_range( level / 2, 3 * level / 2 ) );
  1040. victim->mana /= 2;
  1041. victim->move /= 2;
  1042. dam  = dice(1, level);
  1043. ch->hit += dam;
  1044.     }
  1045.     damage( ch, victim, dam, sn );
  1046.     return;
  1047. }
  1048. void spell_fireball( int sn, int level, CHAR_DATA *ch, void *vo )
  1049. {
  1050.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1051.     static const sh_int dam_each[] = 
  1052.     {
  1053.   0,
  1054.   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
  1055.   0,   0,   0,   0,  30,  35,  40,  45,  50,  55,
  1056.  60,  65,  70,  75,  80,  82,  84,  86,  88,  90,
  1057.  92,  94,  96,  98, 100, 102, 104, 106, 108, 110,
  1058. 112, 114, 116, 118, 120, 122, 124, 126, 128, 130
  1059.     };
  1060.     int dam;
  1061.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  1062.     level = UMAX(0, level);
  1063.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1064.     if ( saves_spell( level, victim ) )
  1065. dam /= 2;
  1066.     damage( ch, victim, dam, sn );
  1067.     return;
  1068. }
  1069. void spell_flamestrike( int sn, int level, CHAR_DATA *ch, void *vo )
  1070. {
  1071.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1072.     int dam;
  1073.     dam = dice(6, level);
  1074.     if ( saves_spell( level, victim ) )
  1075. dam /= 2;
  1076.     damage( ch, victim, dam, sn );
  1077.     return;
  1078. }
  1079. void spell_faerie_fire( int sn, int level, CHAR_DATA *ch, void *vo )
  1080. {
  1081.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1082.     AFFECT_DATA af;
  1083.     if ( IS_AFFECTED(victim, AFF_FAERIE_FIRE) )
  1084. return;
  1085.     af.type      = sn;
  1086.     af.duration  = level;
  1087.     af.location  = APPLY_AC;
  1088.     af.modifier  = 2 * level;
  1089.     af.bitvector = AFF_FAERIE_FIRE;
  1090.     affect_to_char( victim, &af );
  1091.     send_to_char( "You are surrounded by a pink outline.nr", victim );
  1092.     act( "$n is surrounded by a pink outline.", victim, NULL, NULL, TO_ROOM );
  1093.     return;
  1094. }
  1095. void spell_faerie_fog( int sn, int level, CHAR_DATA *ch, void *vo )
  1096. {
  1097.     CHAR_DATA *ich;
  1098.     act( "$n conjures a cloud of purple smoke.", ch, NULL, NULL, TO_ROOM );
  1099.     send_to_char( "You conjure a cloud of purple smoke.nr", ch );
  1100.     for ( ich = ch->in_room->people; ich != NULL; ich = ich->next_in_room )
  1101.     {
  1102. if ( !IS_NPC(ich) && IS_SET(ich->act, PLR_WIZINVIS) )
  1103.     continue;
  1104. if ( ich == ch || saves_spell( level, ich ) )
  1105.     continue;
  1106. affect_strip ( ich, gsn_invis );
  1107. affect_strip ( ich, gsn_mass_invis );
  1108. affect_strip ( ich, gsn_sneak );
  1109. REMOVE_BIT   ( ich->affected_by, AFF_HIDE );
  1110. REMOVE_BIT   ( ich->affected_by, AFF_INVISIBLE );
  1111. REMOVE_BIT   ( ich->affected_by, AFF_SNEAK );
  1112. act( "$n is revealed!", ich, NULL, NULL, TO_ROOM );
  1113. send_to_char( "You are revealed!nr", ich );
  1114.     }
  1115.     return;
  1116. }
  1117. void spell_fly( int sn, int level, CHAR_DATA *ch, void *vo )
  1118. {
  1119.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1120.     AFFECT_DATA af;
  1121.     if ( IS_AFFECTED(victim, AFF_FLYING) )
  1122. return;
  1123.     af.type      = sn;
  1124.     af.duration  = level + 3;
  1125.     af.location  = 0;
  1126.     af.modifier  = 0;
  1127.     af.bitvector = AFF_FLYING;
  1128.     affect_to_char( victim, &af );
  1129.     send_to_char( "Your feet rise off the ground.nr", victim );
  1130.     act( "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
  1131.     return;
  1132. }
  1133. void spell_gate( int sn, int level, CHAR_DATA *ch, void *vo )
  1134. {
  1135.     char_to_room( create_mobile( get_mob_index(MOB_VNUM_VAMPIRE) ),
  1136. ch->in_room );
  1137.     return;
  1138. }
  1139. /*
  1140.  * Spell for mega1.are from Glop/Erkenbrand.
  1141.  */
  1142. void spell_general_purpose( int sn, int level, CHAR_DATA *ch, void *vo )
  1143. {
  1144.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1145.     int dam;
  1146.     dam = number_range( 25, 100 );
  1147.     if ( saves_spell( level, victim ) )
  1148. dam /= 2;
  1149.     damage( ch, victim, dam, sn );
  1150.     return;
  1151. }
  1152. void spell_giant_strength( int sn, int level, CHAR_DATA *ch, void *vo )
  1153. {
  1154.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1155.     AFFECT_DATA af;
  1156.     if ( is_affected( victim, sn ) )
  1157. return;
  1158.     af.type      = sn;
  1159.     af.duration  = level;
  1160.     af.location  = APPLY_STR;
  1161.     af.modifier  = 1 + (level >= 18) + (level >= 25);
  1162.     af.bitvector = 0;
  1163.     affect_to_char( victim, &af );
  1164.     send_to_char( "You feel stronger.nr", victim );
  1165.     if ( ch != victim )
  1166. send_to_char( "Ok.nr", ch );
  1167.     return;
  1168. }
  1169. void spell_harm( int sn, int level, CHAR_DATA *ch, void *vo )
  1170. {
  1171.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1172.     int dam;
  1173.     dam = UMAX(  20, victim->hit - dice(1,4) );
  1174.     if ( saves_spell( level, victim ) )
  1175. dam = UMIN( 50, dam / 4 );
  1176.     dam = UMIN( 100, dam );
  1177.     damage( ch, victim, dam, sn );
  1178.     return;
  1179. }
  1180. void spell_heal( int sn, int level, CHAR_DATA *ch, void *vo )
  1181. {
  1182.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1183.     victim->hit = UMIN( victim->hit + 100, victim->max_hit );
  1184.     update_pos( victim );
  1185.     send_to_char( "A warm feeling fills your body.nr", victim );
  1186.     if ( ch != victim )
  1187. send_to_char( "Ok.nr", ch );
  1188.     return;
  1189. }
  1190. /*
  1191.  * Spell for mega1.are from Glop/Erkenbrand.
  1192.  */
  1193. void spell_high_explosive( int sn, int level, CHAR_DATA *ch, void *vo )
  1194. {
  1195.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1196.     int dam;
  1197.     dam = number_range( 30, 120 );
  1198.     if ( saves_spell( level, victim ) )
  1199. dam /= 2;
  1200.     damage( ch, victim, dam, sn );
  1201.     return;
  1202. }
  1203. void spell_identify( int sn, int level, CHAR_DATA *ch, void *vo )
  1204. {
  1205.     OBJ_DATA *obj = (OBJ_DATA *) vo;
  1206.     char buf[MAX_STRING_LENGTH];
  1207.     AFFECT_DATA *paf;
  1208.     sprintf( buf,
  1209. "Object '%s' is type %s, extra flags %s.nrWeight is %d, value is %d, level is %d.nr",
  1210. obj->name,
  1211. item_type_name( obj ),
  1212. extra_bit_name( obj->extra_flags ),
  1213. obj->weight,
  1214. obj->cost,
  1215. obj->level
  1216. );
  1217.     send_to_char( buf, ch );
  1218.     switch ( obj->item_type )
  1219.     {
  1220.     case ITEM_SCROLL: 
  1221.     case ITEM_POTION:
  1222.     case ITEM_PILL: // @@@
  1223. sprintf( buf, "Level %d spells of:", obj->value[0] );
  1224. send_to_char( buf, ch );
  1225. if ( obj->value[1] >= 0 && obj->value[1] < MAX_SKILL )
  1226. {
  1227.     send_to_char( " '", ch );
  1228.     send_to_char( skill_table[obj->value[1]].name, ch );
  1229.     send_to_char( "'", ch );
  1230. }
  1231. if ( obj->value[2] >= 0 && obj->value[2] < MAX_SKILL )
  1232. {
  1233.     send_to_char( " '", ch );
  1234.     send_to_char( skill_table[obj->value[2]].name, ch );
  1235.     send_to_char( "'", ch );
  1236. }
  1237. if ( obj->value[3] >= 0 && obj->value[3] < MAX_SKILL )
  1238. {
  1239.     send_to_char( " '", ch );
  1240.     send_to_char( skill_table[obj->value[3]].name, ch );
  1241.     send_to_char( "'", ch );
  1242. }
  1243. send_to_char( ".nr", ch );
  1244. break;
  1245.     case ITEM_WAND: 
  1246.     case ITEM_STAFF: 
  1247. sprintf( buf, "Has %d(%d) charges of level %d",
  1248.     obj->value[1], obj->value[2], obj->value[0] );
  1249. send_to_char( buf, ch );
  1250.       
  1251. if ( obj->value[3] >= 0 && obj->value[3] < MAX_SKILL )
  1252. {
  1253.     send_to_char( " '", ch );
  1254.     send_to_char( skill_table[obj->value[3]].name, ch );
  1255.     send_to_char( "'", ch );
  1256. }
  1257. send_to_char( ".nr", ch );
  1258. break;
  1259.       
  1260.     case ITEM_WEAPON:
  1261. sprintf( buf, "Damage is %d to %d (average %d).nr",
  1262.     obj->value[1], obj->value[2],
  1263.     ( obj->value[1] + obj->value[2] ) / 2 );
  1264. send_to_char( buf, ch );
  1265. break;
  1266.     case ITEM_ARMOR:
  1267. sprintf( buf, "Armor class is %d.nr", obj->value[0] );
  1268. send_to_char( buf, ch );
  1269. break;
  1270.     }
  1271.     for ( paf = obj->pIndexData->affected; paf != NULL; paf = paf->next )
  1272.     {
  1273. if ( paf->location != APPLY_NONE && paf->modifier != 0 )
  1274. {
  1275.     sprintf( buf, "Affects %s by %d.nr",
  1276. affect_loc_name( paf->location ), paf->modifier );
  1277.     send_to_char( buf, ch );
  1278. }
  1279.     }
  1280.     for ( paf = obj->affected; paf != NULL; paf = paf->next )
  1281.     {
  1282. if ( paf->location != APPLY_NONE && paf->modifier != 0 )
  1283. {
  1284.     sprintf( buf, "Affects %s by %d.nr",
  1285. affect_loc_name( paf->location ), paf->modifier );
  1286.     send_to_char( buf, ch );
  1287. }
  1288.     }
  1289.     return;
  1290. }
  1291. void spell_infravision( int sn, int level, CHAR_DATA *ch, void *vo )
  1292. {
  1293.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1294.     AFFECT_DATA af;
  1295.     if ( IS_AFFECTED(victim, AFF_INFRARED) )
  1296. return;
  1297.     act( "$n's eyes glow red.nr", ch, NULL, NULL, TO_ROOM );
  1298.     af.type      = sn;
  1299.     af.duration  = 2 * level;
  1300.     af.location  = APPLY_NONE;
  1301.     af.modifier  = 0;
  1302.     af.bitvector = AFF_INFRARED;
  1303.     affect_to_char( victim, &af );
  1304.     send_to_char( "Your eyes glow red.nr", victim );
  1305.     if ( ch != victim )
  1306. send_to_char( "Ok.nr", ch );
  1307.     return;
  1308. }
  1309. void spell_invis( int sn, int level, CHAR_DATA *ch, void *vo )
  1310. {
  1311.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1312.     AFFECT_DATA af;
  1313.     if ( IS_AFFECTED(victim, AFF_INVISIBLE) )
  1314. return;
  1315.     act( "$n fades out of existence.", victim, NULL, NULL, TO_ROOM );
  1316.     af.type      = sn;
  1317.     af.duration  = 24;
  1318.     af.location  = APPLY_NONE;
  1319.     af.modifier  = 0;
  1320.     af.bitvector = AFF_INVISIBLE;
  1321.     affect_to_char( victim, &af );
  1322.     send_to_char( "You fade out of existence.nr", victim );
  1323.     if ( ch != victim )
  1324. send_to_char( "Ok.nr", ch );
  1325.     return;
  1326. }
  1327. void spell_know_alignment( int sn, int level, CHAR_DATA *ch, void *vo )
  1328. {
  1329.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1330.     char *msg;
  1331.     int ap;
  1332.     ap = victim->alignment;
  1333.          if ( ap >  700 ) msg = "$N has an aura as white as the driven snow.";
  1334.     else if ( ap >  350 ) msg = "$N is of excellent moral character.";
  1335.     else if ( ap >  100 ) msg = "$N is often kind and thoughtful.";
  1336.     else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment.";
  1337.     else if ( ap > -350 ) msg = "$N lies to $S friends.";
  1338.     else if ( ap > -700 ) msg = "$N's slash DISEMBOWELS you!";
  1339.     else msg = "I'd rather just not say anything at all about $N.";
  1340.     act( msg, ch, NULL, victim, TO_CHAR );
  1341.     return;
  1342. }
  1343. void spell_lightning_bolt( int sn, int level, CHAR_DATA *ch, void *vo )
  1344. {
  1345.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1346.     static const sh_int dam_each[] = 
  1347.     {
  1348.  0,
  1349.  0,  0,  0,  0,  0,  0,  0,  0, 25, 28,
  1350. 31, 34, 37, 40, 40, 41, 42, 42, 43, 44,
  1351. 44, 45, 46, 46, 47, 48, 48, 49, 50, 50,
  1352. 51, 52, 52, 53, 54, 54, 55, 56, 56, 57,
  1353. 58, 58, 59, 60, 60, 61, 62, 62, 63, 64
  1354.     };
  1355.     int dam;
  1356.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  1357.     level = UMAX(0, level);
  1358.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1359.     if ( saves_spell( level, victim ) )
  1360. dam /= 2;
  1361.     damage( ch, victim, dam, sn );
  1362.     return;
  1363. }
  1364. void spell_locate_object( int sn, int level, CHAR_DATA *ch, void *vo )
  1365. {
  1366.     char buf[MAX_INPUT_LENGTH];
  1367.     char buf1[32768]; // @@@ This is the limit to the response length...
  1368.     OBJ_DATA *obj;
  1369.     OBJ_DATA *in_obj;
  1370.     bool found;
  1371.     buf1[0] = ''; // @@@
  1372.     found = FALSE;
  1373.     for ( obj = object_list; obj != NULL; obj = obj->next )
  1374.     {
  1375. if ( !can_see_obj( ch, obj ) || !is_name( target_name, obj->name ) )
  1376.     continue;
  1377. found = TRUE;
  1378. for ( in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj )
  1379.     ;
  1380. if ( in_obj->carried_by != NULL )
  1381. {
  1382.     sprintf( buf, "%s carried by %s.nr",
  1383. obj->short_descr, PERS(in_obj->carried_by, ch) );
  1384. }
  1385. else
  1386. {
  1387.     sprintf( buf, "%s in %s.nr",
  1388. obj->short_descr, in_obj->in_room == NULL
  1389.     ? "somewhere" : in_obj->in_room->name );
  1390. }
  1391. buf[0] = UPPER(buf[0]);
  1392. // send_to_char( buf, ch ); @@@
  1393.     if (strlen(buf1) + strlen(buf) >= sizeof buf1 - 2) // @@@
  1394.        break;
  1395.     strcat(buf1, buf); // @@@
  1396.     }
  1397.     if ( !found )
  1398. send_to_char( "Nothing like that in hell, earth, or heaven.nr", ch );
  1399.     else // @@@
  1400.     send_to_char( buf1, ch ); // @@@
  1401.     return;
  1402. }
  1403. void spell_magic_missile( int sn, int level, CHAR_DATA *ch, void *vo )
  1404. {
  1405.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1406.     static const sh_int dam_each[] =
  1407.     {
  1408.  0,
  1409.  3,  3,  4,  4,  5,  6,  6,  6,  6,  6,
  1410.  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,
  1411.  9,  9,  9,  9,  9, 10, 10, 10, 10, 10,
  1412. 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
  1413. 13, 13, 13, 13, 13, 14, 14, 14, 14, 14
  1414.     };
  1415.     int dam;
  1416.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  1417.     level = UMAX(0, level);
  1418.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1419.     if ( saves_spell( level, victim ) )
  1420. dam /= 2;
  1421.     damage( ch, victim, dam, sn );
  1422.     return;
  1423. }
  1424. void spell_mass_invis( int sn, int level, CHAR_DATA *ch, void *vo )
  1425. {
  1426.     AFFECT_DATA af;
  1427.     CHAR_DATA *gch;
  1428.     for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
  1429.     {
  1430. if ( !is_same_group( gch, ch ) || IS_AFFECTED(gch, AFF_INVISIBLE) )
  1431.     continue;
  1432. act( "$n slowly fades out of existence.", gch, NULL, NULL, TO_ROOM );
  1433. send_to_char( "You slowly fade out of existence.nr", gch );
  1434. af.type      = sn;
  1435. af.duration  = 24;
  1436. af.location  = APPLY_NONE;
  1437. af.modifier  = 0;
  1438. af.bitvector = AFF_INVISIBLE;
  1439. affect_to_char( gch, &af );
  1440.     }
  1441.     send_to_char( "Ok.nr", ch );
  1442.     return;
  1443. }
  1444. void spell_null( int sn, int level, CHAR_DATA *ch, void *vo )
  1445. {
  1446.     send_to_char( "That's not a spell!nr", ch );
  1447.     return;
  1448. }
  1449. void spell_pass_door( int sn, int level, CHAR_DATA *ch, void *vo )
  1450. {
  1451.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1452.     AFFECT_DATA af;
  1453.     if ( IS_AFFECTED(victim, AFF_PASS_DOOR) )
  1454. return;
  1455.     af.type      = sn;
  1456.     af.duration  = number_fuzzy( level / 4 );
  1457.     af.location  = APPLY_NONE;
  1458.     af.modifier  = 0;
  1459.     af.bitvector = AFF_PASS_DOOR;
  1460.     affect_to_char( victim, &af );
  1461.     act( "$n turns translucent.", victim, NULL, NULL, TO_ROOM );
  1462.     send_to_char( "You turn translucent.nr", victim );
  1463.     return;
  1464. }
  1465. void spell_poison( int sn, int level, CHAR_DATA *ch, void *vo )
  1466. {
  1467.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1468.     AFFECT_DATA af;
  1469.     if ( saves_spell( level, victim ) )
  1470. return;
  1471.     af.type      = sn;
  1472.     af.duration  = level;
  1473.     af.location  = APPLY_STR;
  1474.     af.modifier  = -2;
  1475.     af.bitvector = AFF_POISON;
  1476.     affect_join( victim, &af );
  1477.     send_to_char( "You feel very sick.nr", victim );
  1478.     if ( ch != victim )
  1479. send_to_char( "Ok.nr", ch );
  1480.     return;
  1481. }
  1482. void spell_protection( int sn, int level, CHAR_DATA *ch, void *vo )
  1483. {
  1484.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1485.     AFFECT_DATA af;
  1486.     if ( IS_AFFECTED(victim, AFF_PROTECT) )
  1487. return;
  1488.     af.type      = sn;
  1489.     af.duration  = 24;
  1490.     af.location  = APPLY_NONE;
  1491.     af.modifier  = 0;
  1492.     af.bitvector = AFF_PROTECT;
  1493.     affect_to_char( victim, &af );
  1494.     send_to_char( "You feel protected.nr", victim );
  1495.     if ( ch != victim )
  1496. send_to_char( "Ok.nr", ch );
  1497.     return;
  1498. }
  1499. void spell_refresh( int sn, int level, CHAR_DATA *ch, void *vo )
  1500. {
  1501.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1502.     victim->move = UMIN( victim->move + level, victim->max_move );
  1503.     send_to_char( "You feel less tired.nr", victim );
  1504.     if ( ch != victim )
  1505. send_to_char( "Ok.nr", ch );
  1506.     return;
  1507. }
  1508. void spell_remove_curse( int sn, int level, CHAR_DATA *ch, void *vo )
  1509. {
  1510.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1511.     if ( is_affected( victim, gsn_curse ) )
  1512.     {
  1513. affect_strip( victim, gsn_curse );
  1514. send_to_char( "You feel better.nr", victim );
  1515. if ( ch != victim )
  1516.     send_to_char( "Ok.nr", ch );
  1517.     }
  1518.     return;
  1519. }
  1520. void spell_sanctuary( int sn, int level, CHAR_DATA *ch, void *vo )
  1521. {
  1522.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1523.     AFFECT_DATA af;
  1524.     if ( IS_AFFECTED(victim, AFF_SANCTUARY) )
  1525. return;
  1526.     af.type      = sn;
  1527.     af.duration  = number_fuzzy( level / 8 );
  1528.     af.location  = APPLY_NONE;
  1529.     af.modifier  = 0;
  1530.     af.bitvector = AFF_SANCTUARY;
  1531.     affect_to_char( victim, &af );
  1532.     act( "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM );
  1533.     send_to_char( "You are surrounded by a white aura.nr", victim );
  1534.     return;
  1535. }
  1536. void spell_shield( int sn, int level, CHAR_DATA *ch, void *vo )
  1537. {
  1538.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1539.     AFFECT_DATA af;
  1540.     if ( is_affected( victim, sn ) )
  1541. return;
  1542.     af.type      = sn;
  1543.     af.duration  = 8 + level;
  1544.     af.location  = APPLY_AC;
  1545.     af.modifier  = -20;
  1546.     af.bitvector = 0;
  1547.     affect_to_char( victim, &af );
  1548.     act( "$n is surrounded by a force shield.", victim, NULL, NULL, TO_ROOM );
  1549.     send_to_char( "You are surrounded by a force shield.nr", victim );
  1550.     return;
  1551. }
  1552. void spell_shocking_grasp( int sn, int level, CHAR_DATA *ch, void *vo )
  1553. {
  1554.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1555.     static const int dam_each[] = 
  1556.     {
  1557.  0,
  1558.  0,  0,  0,  0,  0,  0, 20, 25, 29, 33,
  1559. 36, 39, 39, 39, 40, 40, 41, 41, 42, 42,
  1560. 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
  1561. 48, 48, 49, 49, 50, 50, 51, 51, 52, 52,
  1562. 53, 53, 54, 54, 55, 55, 56, 56, 57, 57
  1563.     };
  1564.     int dam;
  1565.     level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  1566.     level = UMAX(0, level);
  1567.     dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1568.     if ( saves_spell( level, victim ) )
  1569. dam /= 2;
  1570.     damage( ch, victim, dam, sn );
  1571.     return;
  1572. }
  1573. void spell_sleep( int sn, int level, CHAR_DATA *ch, void *vo )
  1574. {
  1575.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1576.     AFFECT_DATA af;
  1577.   
  1578.     if ( IS_AFFECTED(victim, AFF_SLEEP)
  1579.     ||   level < victim->level
  1580.     ||   saves_spell( level, victim ) )
  1581. return;
  1582.     af.type      = sn;
  1583.     af.duration  = 4 + level;
  1584.     af.location  = APPLY_NONE;
  1585.     af.modifier  = 0;
  1586.     af.bitvector = AFF_SLEEP;
  1587.     affect_join( victim, &af );
  1588.     if ( IS_AWAKE(victim) )
  1589.     {
  1590. send_to_char( "You feel very sleepy ..... zzzzzz.nr", victim );
  1591. act( "$n goes to sleep.", victim, NULL, NULL, TO_ROOM );
  1592. victim->position = POS_SLEEPING;
  1593.     }
  1594.     return;
  1595. }
  1596. void spell_stone_skin( int sn, int level, CHAR_DATA *ch, void *vo )
  1597. {
  1598.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1599.     AFFECT_DATA af;
  1600.     if ( is_affected( ch, sn ) )
  1601. return;
  1602.     af.type      = sn;
  1603.     af.duration  = level;
  1604.     af.location  = APPLY_AC;
  1605.     af.modifier  = -40;
  1606.     af.bitvector = 0;
  1607.     affect_to_char( victim, &af );
  1608.     act( "$n's skin turns to stone.", victim, NULL, NULL, TO_ROOM );
  1609.     send_to_char( "Your skin turns to stone.nr", victim );
  1610.     return;
  1611. }
  1612. void spell_summon( int sn, int level, CHAR_DATA *ch, void *vo )
  1613. {
  1614.     CHAR_DATA *victim;
  1615.     if ( ( victim = get_char_world( ch, target_name ) ) == NULL
  1616.     ||   victim == ch
  1617.     ||   victim->in_room == NULL
  1618.     ||   IS_SET(victim->in_room->room_flags, ROOM_SAFE)
  1619.     ||   IS_SET(victim->in_room->room_flags, ROOM_PRIVATE)
  1620.     ||   IS_SET(victim->in_room->room_flags, ROOM_SOLITARY)
  1621.     ||   IS_SET(victim->in_room->room_flags, ROOM_NO_RECALL)
  1622.     ||   victim->level >= level + 3
  1623.     ||   victim->fighting != NULL
  1624.     ||   victim->in_room->area != ch->in_room->area
  1625.     ||   (IS_NPC(victim) && saves_spell( level, victim ) ) )
  1626.     {
  1627. send_to_char( "You failed.nr", ch );
  1628. return;
  1629.     }
  1630.     act( "$n disappears suddenly.", victim, NULL, NULL, TO_ROOM );
  1631.     char_from_room( victim );
  1632.     char_to_room( victim, ch->in_room );
  1633.     act( "$n arrives suddenly.", victim, NULL, NULL, TO_ROOM );
  1634.     act( "$N has summoned you!", ch, NULL, victim,   TO_VICT );
  1635.     do_look( victim, "auto" );
  1636.     return;
  1637. }
  1638. void spell_teleport( int sn, int level, CHAR_DATA *ch, void *vo )
  1639. {
  1640.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1641.     ROOM_INDEX_DATA *pRoomIndex;
  1642.     if ( victim->in_room == NULL
  1643.     ||   IS_SET(victim->in_room->room_flags, ROOM_NO_RECALL)
  1644.     || ( !IS_NPC(ch) && victim->fighting != NULL )
  1645.     || ( victim != ch
  1646.     && ( saves_spell( level, victim ) || saves_spell( level, victim ) ) ) )
  1647.     {
  1648. send_to_char( "You failed.nr", ch );
  1649. return;
  1650.     }
  1651.     for ( ; ; )
  1652.     {
  1653. pRoomIndex = get_room_index( number_range( 0, 65535 ) );
  1654. if ( pRoomIndex != NULL )
  1655. if ( !IS_SET(pRoomIndex->room_flags, ROOM_PRIVATE)
  1656. &&   !IS_SET(pRoomIndex->room_flags, ROOM_SOLITARY) )
  1657.     break;
  1658.     }
  1659.     act( "$n slowly fades out of existence.", victim, NULL, NULL, TO_ROOM );
  1660.     char_from_room( victim );
  1661.     char_to_room( victim, pRoomIndex );
  1662.     act( "$n slowly fades into existence.", victim, NULL, NULL, TO_ROOM );
  1663.     do_look( victim, "auto" );
  1664.     return;
  1665. }
  1666. void spell_ventriloquate( int sn, int level, CHAR_DATA *ch, void *vo )
  1667. {
  1668.     char buf1[MAX_STRING_LENGTH];
  1669.     char buf2[MAX_STRING_LENGTH];
  1670.     char speaker[MAX_INPUT_LENGTH];
  1671.     CHAR_DATA *vch;
  1672.     target_name = one_argument( target_name, speaker );
  1673.     sprintf( buf1, "%s says '%s'.nr",              speaker, target_name );
  1674.     sprintf( buf2, "Someone makes %s say '%s'.nr", speaker, target_name );
  1675.     buf1[0] = UPPER(buf1[0]);
  1676.     for ( vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room )
  1677.     {
  1678. if ( !is_name( speaker, vch->name ) )
  1679.     send_to_char( saves_spell( level, vch ) ? buf2 : buf1, vch );
  1680.     }
  1681.     return;
  1682. }
  1683. void spell_weaken( int sn, int level, CHAR_DATA *ch, void *vo )
  1684. {
  1685.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1686.     AFFECT_DATA af;
  1687.     if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
  1688. return;
  1689.     af.type      = sn;
  1690.     af.duration  = level / 2;
  1691.     af.location  = APPLY_STR;
  1692.     af.modifier  = -2;
  1693.     af.bitvector = 0;
  1694.     affect_to_char( victim, &af );
  1695.     send_to_char( "You feel weaker.nr", victim );
  1696.     if ( ch != victim )
  1697. send_to_char( "Ok.nr", ch );
  1698.     return;
  1699. }
  1700. /*
  1701.  * This is for muds that _want_ scrolls of recall.
  1702.  * Ick.
  1703.  */
  1704. void spell_word_of_recall( int sn, int level, CHAR_DATA *ch, void *vo )
  1705. {
  1706.     do_recall( (CHAR_DATA *) vo, "" );
  1707.     return;
  1708. }
  1709. /*
  1710.  * NPC spells.
  1711.  */
  1712. void spell_acid_breath( int sn, int level, CHAR_DATA *ch, void *vo )
  1713. {
  1714.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1715.     OBJ_DATA *obj_lose;
  1716.     OBJ_DATA *obj_next;
  1717.     int dam;
  1718.     int hpch;
  1719.     if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
  1720.     {
  1721. for ( obj_lose = ch->carrying; obj_lose != NULL; obj_lose = obj_next )
  1722. {
  1723.     int iWear;
  1724.     obj_next = obj_lose->next_content;
  1725.     if ( number_bits( 2 ) != 0 )
  1726. continue;
  1727.     switch ( obj_lose->item_type )
  1728.     {
  1729.     case ITEM_ARMOR:
  1730. if ( obj_lose->value[0] > 0 )
  1731. {
  1732.     act( "$p is pitted and etched!",
  1733. victim, obj_lose, NULL, TO_CHAR );
  1734.     if ( ( iWear = obj_lose->wear_loc ) != WEAR_NONE )
  1735. victim->armor -= apply_ac( obj_lose, iWear );
  1736.     obj_lose->value[0] -= 1;
  1737.     obj_lose->cost      = 0;
  1738.     if ( iWear != WEAR_NONE )
  1739. victim->armor += apply_ac( obj_lose, iWear );
  1740. }
  1741. break;
  1742.     case ITEM_CONTAINER:
  1743. act( "$p fumes and dissolves!",
  1744.     victim, obj_lose, NULL, TO_CHAR );
  1745. extract_obj( obj_lose );
  1746. break;
  1747.     }
  1748. }
  1749.     }
  1750.     hpch = UMAX( 10, ch->hit );
  1751.     dam  = number_range( hpch/16+1, hpch/8 );
  1752.     if ( saves_spell( level, victim ) )
  1753. dam /= 2;
  1754.     damage( ch, victim, dam, sn );
  1755.     return;
  1756. }
  1757. void spell_fire_breath( int sn, int level, CHAR_DATA *ch, void *vo )
  1758. {
  1759.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1760.     OBJ_DATA *obj_lose;
  1761.     OBJ_DATA *obj_next;
  1762.     int dam;
  1763.     int hpch;
  1764.     if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
  1765.     {
  1766. for ( obj_lose = victim->carrying; obj_lose != NULL;
  1767. obj_lose = obj_next )
  1768. {
  1769.     char *msg;
  1770.     obj_next = obj_lose->next_content;
  1771.     if ( number_bits( 2 ) != 0 )
  1772. continue;
  1773.     switch ( obj_lose->item_type )
  1774.     {
  1775.     default:             continue;
  1776.     case ITEM_CONTAINER: msg = "$p ignites and burns!";   break;
  1777.     case ITEM_POTION:    msg = "$p bubbles and boils!";   break;
  1778.     case ITEM_SCROLL:    msg = "$p crackles and burns!";  break;
  1779.     case ITEM_STAFF:     msg = "$p smokes and chars!";    break;
  1780.     case ITEM_WAND:      msg = "$p sparks and sputters!"; break;
  1781.     case ITEM_FOOD:      msg = "$p blackens and crisps!"; break;
  1782.     case ITEM_PILL:      msg = "$p melts and drips!";     break;
  1783.     }
  1784.     act( msg, victim, obj_lose, NULL, TO_CHAR );
  1785.     extract_obj( obj_lose );
  1786. }
  1787.     }
  1788.     hpch = UMAX( 10, ch->hit );
  1789.     dam  = number_range( hpch/16+1, hpch/8 );
  1790.     if ( saves_spell( level, victim ) )
  1791. dam /= 2;
  1792.     damage( ch, victim, dam, sn );
  1793.     return;
  1794. }
  1795. void spell_frost_breath( int sn, int level, CHAR_DATA *ch, void *vo )
  1796. {
  1797.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1798.     OBJ_DATA *obj_lose;
  1799.     OBJ_DATA *obj_next;
  1800.     int dam;
  1801.     int hpch;
  1802.     if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
  1803.     {
  1804. for ( obj_lose = victim->carrying; obj_lose != NULL;
  1805. obj_lose = obj_next )
  1806. {
  1807.     char *msg;
  1808.     obj_next = obj_lose->next_content;
  1809.     if ( number_bits( 2 ) != 0 )
  1810. continue;
  1811.     switch ( obj_lose->item_type )
  1812.     {
  1813.     default:            continue;
  1814.     case ITEM_CONTAINER:
  1815.     case ITEM_DRINK_CON:
  1816.     case ITEM_POTION:   msg = "$p freezes and shatters!"; break;
  1817.     }
  1818.     act( msg, victim, obj_lose, NULL, TO_CHAR );
  1819.     extract_obj( obj_lose );
  1820. }
  1821.     }
  1822.     hpch = UMAX( 10, ch->hit );
  1823.     dam  = number_range( hpch/16+1, hpch/8 );
  1824.     if ( saves_spell( level, victim ) )
  1825. dam /= 2;
  1826.     damage( ch, victim, dam, sn );
  1827.     return;
  1828. }
  1829. void spell_gas_breath( int sn, int level, CHAR_DATA *ch, void *vo )
  1830. {
  1831.     CHAR_DATA *vch;
  1832.     CHAR_DATA *vch_next;
  1833.     int dam;
  1834.     int hpch;
  1835.     for ( vch = ch->in_room->people; vch != NULL; vch = vch_next )
  1836.     {
  1837. vch_next = vch->next_in_room;
  1838. if ( IS_NPC(ch) ? !IS_NPC(vch) : IS_NPC(vch) )
  1839. {
  1840.     hpch = UMAX( 10, ch->hit );
  1841.     dam  = number_range( hpch/16+1, hpch/8 );
  1842.     if ( saves_spell( level, vch ) )
  1843. dam /= 2;
  1844.     damage( ch, vch, dam, sn );
  1845. }
  1846.     }
  1847.     return;
  1848. }
  1849. void spell_lightning_breath( int sn, int level, CHAR_DATA *ch, void *vo )
  1850. {
  1851.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1852.     int dam;
  1853.     int hpch;
  1854.     hpch = UMAX( 10, ch->hit );
  1855.     dam = number_range( hpch/16+1, hpch/8 );
  1856.     if ( saves_spell( level, victim ) )
  1857. dam /= 2;
  1858.     damage( ch, victim, dam, sn );
  1859.     return;
  1860. }
  1861. /*
  1862.  * Code for Psionicist spells/skills by Thelonius
  1863.  */
  1864. void spell_adrenaline_control ( int sn, int level, CHAR_DATA *ch, void *vo )
  1865. {
  1866.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  1867.     AFFECT_DATA af;
  1868.     if ( is_affected( victim, sn ) )
  1869.         return;
  1870.     af.type  = sn;
  1871.     af.duration  = level - 5;
  1872.     af.location  = APPLY_DEX;
  1873.     af.modifier  = 2;
  1874.     af.bitvector = 0;
  1875.     affect_to_char( victim, &af );
  1876.     af.location = APPLY_CON;
  1877.     affect_to_char( victim, &af );
  1878.     send_to_char( "You have given yourself an adrenaline rush!nr", ch );
  1879.     act( "$n has given $mself an adrenaline rush!", ch, NULL, NULL,
  1880. TO_ROOM );
  1881.    
  1882.     return;
  1883. }
  1884. void spell_agitation ( int sn, int level, CHAR_DATA *ch, void *vo )
  1885. {
  1886.                  CHAR_DATA *victim       = (CHAR_DATA *) vo;
  1887.     static const int        dam_each [ ] =
  1888.     {
  1889. 0,
  1890.  0,  0,  0,  0,  0,      12, 15, 18, 21, 24,
  1891. 24, 24, 25, 25, 26,      26, 26, 27, 27, 27,
  1892. 28, 28, 28, 29, 29,      29, 30, 30, 30, 31,
  1893. 31, 31, 32, 32, 32,      33, 33, 33, 34, 34,
  1894. 34, 35, 35, 35, 36,      36, 36, 37, 37, 37
  1895.     };
  1896.  int        dam;
  1897.     level    = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
  1898.     level    = UMAX( 0, level );
  1899.     dam      = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1900.    
  1901.     if ( saves_spell( level, victim ) )
  1902.       dam /= 2;
  1903.     damage( ch, victim, dam, sn );
  1904.     return;
  1905. }
  1906. void spell_aura_sight ( int sn, int level, CHAR_DATA *ch, void *vo )
  1907. {
  1908.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1909.     char      *msg;
  1910.     int        ap;
  1911.    
  1912.     ap = victim->alignment;
  1913.     if ( ap >  700 ) msg = "$N has an aura as white as the driven snow.";
  1914.     else if ( ap >  350 ) msg = "$N is of excellent moral character.";
  1915.     else if ( ap >  100 ) msg = "$N is often kind and thoughtful.";
  1916.     else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment.";
  1917.     else if ( ap > -350 ) msg = "$N lies to $S friends.";
  1918.     else if ( ap > -700 ) msg = "Don't bring $N home to meet your family.";
  1919.     else msg = "Uh, check please!";
  1920.     act( msg, ch, NULL, victim, TO_CHAR );
  1921. }
  1922. void spell_awe ( int sn, int level, CHAR_DATA *ch, void *vo )
  1923.   {
  1924.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1925.     if ( victim->fighting == ch && !saves_spell( level, victim ) )
  1926.     {
  1927. stop_fighting ( victim, TRUE);
  1928. act( "$N is in AWE of you!", ch, NULL, victim, TO_CHAR    );
  1929. act( "You are in AWE of $n!",ch, NULL, victim, TO_VICT    );
  1930. act( "$N is in AWE of $n!",  ch, NULL, victim, TO_NOTVICT );
  1931.     }
  1932.     return;
  1933. }
  1934. void spell_ballistic_attack ( int sn, int level, CHAR_DATA *ch, void *vo )
  1935.   {
  1936.                  CHAR_DATA *victim       = (CHAR_DATA *) vo;
  1937.     static const int        dam_each [ ] =
  1938.     {
  1939.  0,
  1940.  3,  4,  4,  5,  6,       6,  6,  7,  7,  7,
  1941.  7,  7,  8,  8,  8,       9,  9,  9, 10, 10,
  1942. 10, 11, 11, 11, 12,      12, 12, 13, 13, 13,
  1943. 14, 14, 14, 15, 15,      15, 16, 16, 16, 17,
  1944. 17, 17, 18, 18, 18,      19, 19, 19, 20, 20
  1945.     };
  1946.  int        dam;
  1947.     level    = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
  1948.     level    = UMAX( 0, level );
  1949.     dam      = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  1950.     if ( saves_spell( level, victim ) )
  1951.       dam /= 2;
  1952.     act( "You chuckle as a stone strikes $N.", ch, NULL, victim,
  1953. TO_CHAR );
  1954.     damage( ch, victim, dam, sn);
  1955.     return;
  1956. }
  1957. void spell_biofeedback ( int sn, int level, CHAR_DATA *ch, void *vo )
  1958. {
  1959.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  1960.     AFFECT_DATA af;
  1961.    
  1962.     if ( IS_AFFECTED( victim, AFF_SANCTUARY ) )
  1963.         return;
  1964.     af.type      = sn;
  1965.     af.duration  = number_fuzzy( level / 8 );
  1966.     af.location  = APPLY_NONE;
  1967.     af.modifier  = 0;
  1968.     af.bitvector = AFF_SANCTUARY;
  1969.     affect_to_char( victim, &af );
  1970.     send_to_char( "You are surrounded by a white aura.nr", victim );
  1971.     act( "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM );
  1972.     return;
  1973. }
  1974. void spell_cell_adjustment ( int sn, int level, CHAR_DATA *ch, void *vo )
  1975. {
  1976.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  1977.    
  1978.     if ( is_affected( victim, gsn_poison ) )
  1979.     {
  1980. affect_strip( victim, gsn_poison );
  1981. send_to_char( "A warm feeling runs through your body.nr", victim );
  1982. act( "$N looks better.", ch, NULL, victim, TO_NOTVICT );
  1983.     }
  1984.     if ( is_affected( victim, gsn_curse  ) )
  1985.     {
  1986. affect_strip( victim, gsn_curse  );
  1987. send_to_char( "You feel better.nr", victim );
  1988.     }
  1989.     send_to_char( "Ok.nr", ch );
  1990.     return;
  1991. }
  1992. void spell_combat_mind ( int sn, int level, CHAR_DATA *ch, void *vo )
  1993. {
  1994.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  1995.     AFFECT_DATA af;
  1996.     if ( is_affected( victim, sn ) )
  1997.     {
  1998. if ( victim == ch )
  1999.   send_to_char( "You already understand battle tactics.nr",
  2000.        victim );
  2001. else
  2002.   act( "$N already understands battle tactics.",
  2003.       ch, NULL, victim, TO_CHAR );
  2004. return;
  2005.     }
  2006.     af.type  = sn;
  2007.     af.duration  = level + 3;
  2008.     af.location  = APPLY_HITROLL;
  2009.     af.modifier  = level / 6;
  2010.     af.bitvector = 0;
  2011.     affect_to_char( victim, &af );
  2012.     af.location  = APPLY_AC;
  2013.     af.modifier  = - level/2 - 5;
  2014.     affect_to_char( victim, &af );
  2015.     if ( victim != ch )
  2016.         send_to_char( "OK.nr", ch );
  2017.     send_to_char( "You gain a keen understanding of battle tactics.nr",
  2018.  victim );
  2019.     return;
  2020. }
  2021. void spell_complete_healing ( int sn, int level, CHAR_DATA *ch, void *vo )
  2022. {
  2023.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  2024.     victim->hit = victim->max_hit;
  2025.     update_pos( victim );
  2026.     if ( ch != victim )
  2027.         send_to_char( "Ok.nr", ch );
  2028.     send_to_char( "Ahhhhhh...You are completely healed!nr", victim );
  2029.     return;
  2030. }
  2031. void spell_control_flames ( int sn, int level, CHAR_DATA *ch, void *vo )
  2032. {
  2033.                  CHAR_DATA *victim       = (CHAR_DATA *) vo;
  2034.     static const int        dam_each [ ] = 
  2035.     {
  2036.  0,
  2037.  0,  0,  0,  0,  0,       0,  0, 16, 20, 24,
  2038. 28, 32, 35, 38, 40,      42, 44, 45, 45, 45,
  2039. 46, 46, 46, 47, 47,      47, 48, 48, 48, 49,
  2040. 49, 49, 50, 50, 50,      51, 51, 51, 52, 52,
  2041. 52, 53, 53, 53, 54,      54, 54, 55, 55, 55
  2042.     };
  2043.  int        dam;
  2044.     if ( !get_eq_char( ch, WEAR_LIGHT ) )
  2045.     {
  2046. send_to_char( "You must be carrying a light source.nr", ch );
  2047. return;
  2048.     }
  2049.     level    = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
  2050.     level    = UMAX( 0, level );
  2051.     dam      = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  2052.     if ( saves_spell( level, victim ) )
  2053.         dam /= 2;
  2054.     damage( ch, victim, dam, sn );
  2055.     return;
  2056. }
  2057. void spell_create_sound ( int sn, int level, CHAR_DATA *ch, void *vo )
  2058. {
  2059.     CHAR_DATA *vch;
  2060.     char       buf1    [ MAX_STRING_LENGTH ];
  2061.     char       buf2    [ MAX_STRING_LENGTH ];
  2062.     char       speaker [ MAX_INPUT_LENGTH  ];
  2063.     target_name = one_argument( target_name, speaker );
  2064.     sprintf( buf1, "%s says '%s'.nr", speaker, target_name );
  2065.     sprintf( buf2, "Someone makes %s say '%s'.nr", speaker, target_name );
  2066.     buf1[0] = UPPER( buf1[0] );
  2067.     for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
  2068.     {
  2069. if ( !is_name( speaker, vch->name ) )
  2070.     send_to_char( saves_spell( level, vch ) ? buf2 : buf1, vch );
  2071.     }
  2072.     return;
  2073. }
  2074. void spell_death_field ( int sn, int level, CHAR_DATA *ch, void *vo )
  2075. {
  2076.     CHAR_DATA *vch;
  2077.     CHAR_DATA *vch_next;
  2078.     int        dam;
  2079.     int        hpch;
  2080.     if ( !IS_EVIL( ch ) )
  2081.     {
  2082. send_to_char( "You are not evil enough to do that!nr", ch);
  2083. return;
  2084.     }
  2085.     send_to_char( "A black haze emanates from you!nr", ch );
  2086.     act ( "A black haze emanates from $n!", ch, NULL, ch, TO_ROOM );
  2087.     for ( vch = ch->in_room->people; vch; vch = vch_next )
  2088.     {
  2089.         vch_next = vch->next_in_room;
  2090. //@@@ if ( vch->deleted )
  2091. //@@@   continue;
  2092. if ( !IS_NPC( ch ) ? IS_NPC( vch ) : IS_NPC( vch ) )
  2093. {
  2094.     hpch = URANGE( 10, ch->hit, 999 );
  2095.     if ( !saves_spell( level, vch )
  2096. && (   level <= vch->level + 5
  2097.     && level >= vch->level - 5 ) )
  2098.             {
  2099. dam = 4; /* Enough to compensate for sanct. and prot. */
  2100. vch->hit = 1;
  2101. update_pos( vch );
  2102. send_to_char( "The haze envelops you!nr", vch );
  2103. act( "The haze envelops $N!", ch, NULL, vch, TO_ROOM );
  2104.             }
  2105.     else
  2106.         dam = number_range( hpch / 16 + 1, hpch / 8 );
  2107.     damage( ch, vch, dam, sn );
  2108.         }
  2109.     }
  2110.     return;
  2111. }
  2112. void spell_detonate ( int sn, int level, CHAR_DATA *ch, void *vo )
  2113. {
  2114.                  CHAR_DATA *victim       = (CHAR_DATA *) vo;
  2115.     static const int        dam_each [ ] =
  2116.     {
  2117.   0,
  2118.   0,   0,   0,   0,   0,        0,   0,   0,   0,   0,
  2119.   0,   0,   0,   0,   0,        0,   0,   0,   0,  75,
  2120.  80,  85,  90,  95, 100,      102, 104, 106, 108, 110,
  2121. 112, 114, 116, 118, 120,      122, 124, 126, 128, 130,
  2122. 132, 134, 136, 138, 140,      142, 144, 146, 148, 150
  2123.     };
  2124.  int        dam;
  2125.     level    = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
  2126.     level    = UMAX( 0, level );
  2127.     dam      = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  2128.     if ( saves_spell( level, victim ) )
  2129.         dam /= 2;
  2130.     damage( ch, victim, dam, sn );
  2131.     return;
  2132. }
  2133. void spell_disintegrate ( int sn, int level, CHAR_DATA *ch, void *vo )
  2134. {
  2135.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  2136.     OBJ_DATA  *obj_lose;
  2137.     OBJ_DATA  *obj_next;
  2138.     if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
  2139.       for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
  2140.       {
  2141.   obj_next = obj_lose->next_content;
  2142. //   if ( obj_lose->deleted )
  2143. //       continue;
  2144.   if ( number_bits( 2 ) != 0 )
  2145.       continue;
  2146.   act( "$p disintegrates!",      victim, obj_lose, NULL, TO_CHAR );
  2147.   act( "$n's $p disintegrates!", victim, obj_lose, NULL, TO_ROOM );
  2148.   extract_obj( obj_lose ) ;
  2149.       }
  2150.     if ( !saves_spell( level, victim ) )
  2151.     /*
  2152.      * Disintegrate char, do not generate a corpse, do not
  2153.      * give experience for kill.  Extract_char will take care
  2154.      * of items carried/wielded by victim.  Needless to say,
  2155.      * it would be bad to be a target of this spell!
  2156.      * --- Thelonius (Monk)
  2157.      */
  2158.     {
  2159. act( "You have DISINTEGRATED $N!",         ch, NULL, victim, TO_CHAR );
  2160. act( "You have been DISINTEGRATED by $n!", ch, NULL, victim, TO_VICT );
  2161. act( "$n's spell DISINTEGRATES $N!",       ch, NULL, victim, TO_ROOM );
  2162. if ( IS_NPC( victim ) )
  2163.     extract_char( victim, TRUE );
  2164. else
  2165.     extract_char( victim, FALSE );
  2166.     }
  2167.     return;
  2168. }
  2169. void spell_displacement ( int sn, int level, CHAR_DATA *ch, void *vo )
  2170. {
  2171.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2172.     AFFECT_DATA af;
  2173.     if ( is_affected( victim, sn ) )
  2174. return;
  2175.     af.type  = sn;
  2176.     af.duration  = level - 4;
  2177.     af.location  = APPLY_AC;
  2178.     af.modifier  = 4 - level;
  2179.     af.bitvector = 0;
  2180.     affect_to_char( victim, &af );
  2181.     send_to_char( "Your form shimmers, and you appear displaced.nr",
  2182.  victim );
  2183.     act( "$N shimmers and appears in a different location.",
  2184. ch, NULL, victim, TO_NOTVICT );
  2185.     return;
  2186. }
  2187. void spell_domination ( int sn, int level, CHAR_DATA *ch, void *vo )
  2188. {
  2189.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2190.     AFFECT_DATA af;
  2191.     if ( victim == ch )
  2192.     {
  2193. send_to_char( "Dominate yourself?  You're weird.nr", ch );
  2194. return;
  2195.     }
  2196.     if (   IS_AFFECTED( victim, AFF_CHARM )
  2197. || IS_AFFECTED( ch,     AFF_CHARM )
  2198. || level < victim->level
  2199. || saves_spell( level, victim ) )
  2200.         return;
  2201.     if ( victim->master )
  2202.         stop_follower( victim );
  2203.     add_follower( victim, ch );
  2204.     af.type  = sn;
  2205.     af.duration  = number_fuzzy( level / 4 );
  2206.     af.location  = APPLY_NONE;
  2207.     af.modifier  = 0;
  2208.     af.bitvector = AFF_CHARM;
  2209.     affect_to_char( victim, &af );
  2210.     act( "Your will dominates $N!", ch, NULL, victim, TO_CHAR );
  2211.     act( "Your will is dominated by $n!", ch, NULL, victim, TO_VICT );
  2212.     return;
  2213. }
  2214. void spell_ectoplasmic_form ( int sn, int level, CHAR_DATA *ch, void *vo )
  2215. {
  2216.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2217.     AFFECT_DATA af;
  2218.     if ( IS_AFFECTED( victim, AFF_PASS_DOOR ) )
  2219.         return;
  2220.     af.type  = sn;
  2221.     af.duration  = number_fuzzy( level / 4 );
  2222.     af.location  = APPLY_NONE;
  2223.     af.modifier  = 0;
  2224.     af.bitvector = AFF_PASS_DOOR;
  2225.     affect_to_char( victim, &af );
  2226.     send_to_char( "You turn translucent.nr", victim );
  2227.     act( "$n turns translucent.", victim, NULL, NULL, TO_ROOM );
  2228.     return;
  2229. }
  2230. void spell_ego_whip ( int sn, int level, CHAR_DATA *ch, void *vo )
  2231. {
  2232.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2233.     AFFECT_DATA af;
  2234.     if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
  2235.         return;
  2236.     af.type  = sn;
  2237.     af.duration  = level;
  2238.     af.location  = APPLY_HITROLL;
  2239.     af.modifier  = -2;
  2240.     af.bitvector = 0;
  2241.     affect_to_char( victim, &af );
  2242.     af.location  = APPLY_SAVING_SPELL;
  2243.     af.modifier  = 2;
  2244.     affect_to_char( victim, &af );
  2245.     af.location  = APPLY_AC;
  2246.     af.modifier  = level / 2;
  2247.     affect_to_char( victim, &af );
  2248.     act( "You ridicule $N about $S childhood.", ch, NULL, victim, TO_CHAR    );
  2249.     send_to_char( "Your ego takes a beating.nr", victim );
  2250.     act( "$N's ego is crushed by $n!",          ch, NULL, victim, TO_NOTVICT );
  2251.     return;
  2252. }
  2253. void spell_energy_containment ( int sn, int level, CHAR_DATA *ch, void *vo )
  2254. {
  2255.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2256.     AFFECT_DATA af;
  2257.     if ( is_affected( victim, sn ) )
  2258.         return;
  2259.     af.type  = sn;
  2260.     af.duration  = level / 2 + 7;
  2261.     af.modifier  = -level / 5;
  2262.     af.location  = APPLY_SAVING_SPELL;
  2263.     af.bitvector = 0;
  2264.     affect_to_char( victim, &af );
  2265.     send_to_char( "You can now absorb some forms of energy.nr", ch );
  2266.     return;
  2267. }
  2268. void spell_enhance_armor (int sn, int level, CHAR_DATA *ch, void *vo )
  2269. {
  2270.     OBJ_DATA    *obj = (OBJ_DATA *) vo;
  2271.     AFFECT_DATA *paf;
  2272.     if ( obj->item_type != ITEM_ARMOR
  2273. || IS_OBJ_STAT( obj, ITEM_MAGIC )
  2274. || obj->affected )
  2275.     {
  2276. send_to_char( "That item cannot be enhanced.nr", ch );
  2277. return;
  2278.     }
  2279.     if ( !affect_free )
  2280.     {
  2281. paf     = alloc_perm( sizeof( *paf ) );
  2282.     }
  2283.     else
  2284.     {
  2285. paf         = affect_free;
  2286. affect_free = affect_free->next;
  2287.     }
  2288.     paf->type    = sn;
  2289.     paf->duration  = -1;
  2290.     paf->location  = APPLY_AC;
  2291.     paf->bitvector = 0;
  2292.     paf->next    = obj->affected;
  2293.     obj->affected  = paf;
  2294.     if ( number_percent() < ch->pcdata->learned[sn]/2
  2295. + 3 * ( ch->level - obj->level ) )
  2296.     /* Good enhancement */
  2297.     {
  2298. paf->modifier   = -level / 8;
  2299.      if ( IS_GOOD( ch ) )
  2300. {
  2301.     SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
  2302.     act( "$p glows blue.",   ch, obj, NULL, TO_CHAR );
  2303. }
  2304. else if ( IS_EVIL( ch ) )
  2305.         {
  2306.     SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
  2307.     act( "$p glows red.",    ch, obj, NULL, TO_CHAR );
  2308. }
  2309. else
  2310. {
  2311.     SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
  2312.     SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
  2313.     act( "$p glows yellow.", ch, obj, NULL, TO_CHAR );
  2314. }
  2315.        
  2316. send_to_char( "Ok.nr", ch );
  2317.     }
  2318.     else
  2319.     /* Bad Enhancement ... opps! :) */
  2320.     {
  2321. paf->modifier   = level / 8;
  2322. obj->cost       = 0;
  2323. SET_BIT( obj->extra_flags, ITEM_NODROP );
  2324. act( "$p turns black.", ch, obj, NULL, TO_CHAR );
  2325.     }
  2326.     return;
  2327. }
  2328. void spell_enhanced_strength ( int sn, int level, CHAR_DATA *ch, void *vo )
  2329. {
  2330.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2331.     AFFECT_DATA af;
  2332.     if ( is_affected( victim, sn ) )
  2333.         return;
  2334.     af.type  = sn;
  2335.     af.duration  = level;
  2336.     af.location  = APPLY_STR;
  2337.     af.modifier  = 1 + ( level >= 15 ) + ( level >= 25 );
  2338.     af.bitvector = 0;
  2339.     affect_to_char( victim, &af );
  2340.     send_to_char( "You are HUGE!nr", victim );
  2341.     return;
  2342. }
  2343. void spell_flesh_armor ( int sn, int level, CHAR_DATA *ch, void *vo )
  2344. {
  2345.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2346.     AFFECT_DATA af;
  2347.     if ( is_affected( victim, sn ) )
  2348.         return;
  2349.     af.type  = sn;
  2350.     af.duration  = level;
  2351.     af.location  = APPLY_AC;
  2352.     af.modifier  = -40;
  2353.     af.bitvector = 0;
  2354.     affect_to_char( victim, &af );
  2355.     send_to_char( "Your flesh turns to steel.nr", victim );
  2356.     act( "$N's flesh turns to steel.", ch, NULL, victim, TO_NOTVICT);
  2357.     return;
  2358. }
  2359. void spell_inertial_barrier ( int sn, int level, CHAR_DATA *ch, void *vo )
  2360. {
  2361.     CHAR_DATA  *gch;
  2362.     AFFECT_DATA af;
  2363.     for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
  2364.     {
  2365. if ( !is_same_group( gch, ch ) || IS_AFFECTED( gch, AFF_PROTECT ) )
  2366.     continue;
  2367. act( "An inertial barrier forms around $n.", gch, NULL, NULL,
  2368.     TO_ROOM );
  2369. send_to_char( "An inertial barrier forms around you.nr", gch );
  2370. af.type      = sn;
  2371. af.duration  = 24;
  2372. af.modifier  = 0;
  2373. af.location  = APPLY_NONE;
  2374. af.bitvector = AFF_PROTECT;
  2375. affect_to_char( gch, &af );
  2376.     }
  2377.     return;
  2378. }
  2379. void spell_inflict_pain ( int sn, int level, CHAR_DATA *ch, void *vo )
  2380. {
  2381.     damage( ch, (CHAR_DATA *) vo, dice( 2, 10 ) + level / 2, sn );
  2382.     return;
  2383. }
  2384. void spell_intellect_fortress ( int sn, int level, CHAR_DATA *ch, void *vo )
  2385. {
  2386.     CHAR_DATA  *gch;
  2387.     AFFECT_DATA af;
  2388.     for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
  2389.     {
  2390. if ( !is_same_group( gch, ch ) || is_affected( gch, sn ) )
  2391.     continue;
  2392. send_to_char( "A virtual fortress forms around you.nr", gch );
  2393. act( "A virtual fortress forms around $N.", gch, NULL, gch, TO_ROOM );
  2394. af.type      = sn;
  2395. af.duration  = 24;
  2396. af.location  = APPLY_AC;
  2397. af.modifier  = -40;
  2398. af.bitvector = 0;
  2399. affect_to_char( gch, &af );
  2400.     }
  2401.     return;
  2402. }
  2403. void spell_lend_health ( int sn, int level, CHAR_DATA *ch, void *vo )
  2404. {
  2405.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  2406.     int        hpch;
  2407.     if ( ch == victim )
  2408.     {
  2409. send_to_char( "Lend health to yourself?  What a weirdo.nr", ch );
  2410. return;
  2411.     }
  2412.     hpch = UMIN( 50, victim->max_hit - victim->hit );
  2413.     if ( hpch == 0 )
  2414.     {
  2415. act( "Nice thought, but $N doesn't need healing.", ch, NULL,
  2416.     victim, TO_CHAR );
  2417. return;
  2418.     }
  2419.     if ( ch->hit-hpch < 50 )
  2420.     {
  2421. send_to_char( "You aren't healthy enough yourself!nr", ch );
  2422. return;
  2423.     }
  2424.     victim->hit += hpch;
  2425.     ch->hit     -= hpch;
  2426.     update_pos( victim );
  2427.     update_pos( ch );
  2428.     act( "You lend some of your health to $N.", ch, NULL, victim, TO_CHAR );
  2429.     act( "$n lends you some of $s health.",     ch, NULL, victim, TO_VICT );
  2430.     return;
  2431. }
  2432. void spell_levitation ( int sn, int level, CHAR_DATA *ch, void *vo )
  2433. {
  2434.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  2435.     AFFECT_DATA af;
  2436.     if ( IS_AFFECTED( victim, AFF_FLYING ) )
  2437.         return;
  2438.     af.type  = sn;
  2439.     af.duration  = level + 3;
  2440.     af.location  = APPLY_NONE;
  2441.     af.modifier  = 0;
  2442.     af.bitvector = AFF_FLYING;
  2443.     affect_to_char( victim, &af );
  2444.     send_to_char( "Your feet rise off the ground.nr", victim );
  2445.     act( "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
  2446.     return;
  2447. }
  2448. void spell_mental_barrier ( int sn, int level, CHAR_DATA *ch, void *vo )
  2449. {
  2450.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2451.     AFFECT_DATA af;
  2452.     if ( is_affected( victim, sn ) )
  2453.         return;
  2454.     af.type  = sn;
  2455.     af.duration  = 24;
  2456.     af.location  = APPLY_AC;
  2457.     af.modifier  = -20;
  2458.     af.bitvector = 0;
  2459.     affect_to_char( victim, &af );
  2460.     send_to_char( "You erect a mental barrier around yourself.nr",
  2461.  victim );
  2462.     return;
  2463. }
  2464. void spell_mind_thrust ( int sn, int level, CHAR_DATA *ch, void *vo )
  2465. {
  2466.     damage( ch, (CHAR_DATA *) vo, dice( 1, 10 ) + level / 2, sn );
  2467.     return;
  2468. }
  2469. void spell_project_force ( int sn, int level, CHAR_DATA *ch, void *vo )
  2470. {
  2471.     damage( ch, (CHAR_DATA *) vo, dice( 4, 6 ) + level, sn );
  2472.     return;
  2473. }
  2474. void spell_psionic_blast ( int sn, int level, CHAR_DATA *ch, void *vo )
  2475. {
  2476.                  CHAR_DATA *victim       = (CHAR_DATA *) vo;
  2477.     static const int        dam_each [ ] =
  2478.     {
  2479.   0,
  2480.   0,   0,   0,   0,   0,        0,   0,   0,   0,   0,
  2481.   0,   0,   0,   0,   0,        0,  45,  50,  55,  60,
  2482.  64,  68,  72,  76,  80,       82,  84,  86,  88,  90,
  2483.  92,  94,  96,  98, 100,      102, 104, 106, 108, 100,
  2484. 112, 114, 116, 118, 120,      122, 124, 126, 128, 130
  2485.     };
  2486.  int        dam;
  2487.     level    = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
  2488.     level    = UMAX( 0, level );
  2489.     dam      = number_range( dam_each[level] / 2, dam_each[level] * 2 );
  2490.     if ( saves_spell( level, victim ) )
  2491.         dam /= 2;
  2492.     damage( ch, victim, dam, sn );
  2493.     return;
  2494. }
  2495. void spell_psychic_crush ( int sn, int level, CHAR_DATA *ch, void *vo )
  2496. {
  2497.     damage( ch, (CHAR_DATA *) vo, dice( 3, 5 ) + level, sn );
  2498.     return;
  2499. }
  2500. void spell_psychic_drain ( int sn, int level, CHAR_DATA *ch, void *vo )
  2501. {
  2502.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2503.     AFFECT_DATA af;
  2504.     if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
  2505.         return;
  2506.     af.type  = sn;
  2507.     af.duration  = level / 2;
  2508.     af.location  = APPLY_STR;
  2509.     af.modifier  = -1 - ( level >= 10 ) - ( level >= 20 ) - ( level >= 30 );
  2510.     af.bitvector = 0;
  2511.     affect_to_char( victim, &af );
  2512.     send_to_char( "You feel drained.nr", victim );
  2513.     act( "$n appears drained of strength.", victim, NULL, NULL, TO_ROOM );
  2514.     return;
  2515. }
  2516. void spell_psychic_healing ( int sn, int level, CHAR_DATA *ch, void *vo )
  2517. {
  2518.     CHAR_DATA *victim = (CHAR_DATA *) vo;
  2519.     int heal;
  2520.     heal = dice( 3, 6 ) + 2 * level / 3 ;
  2521.     victim->hit = UMIN( victim->hit + heal, victim->max_hit );
  2522.     update_pos( victim );
  2523.     send_to_char( "You feel better!nr", victim );
  2524.     return;
  2525. }
  2526. void spell_share_strength ( int sn, int level, CHAR_DATA *ch, void *vo )
  2527. {
  2528.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2529.     AFFECT_DATA af;
  2530.     if ( victim == ch )
  2531.     {
  2532. send_to_char( "You can't share strength with yourself.nr", ch );
  2533. return;
  2534.     }
  2535.     if ( is_affected( victim, sn ) )
  2536.     {
  2537. act( "$N already shares someone's strength.", ch, NULL, victim,
  2538.     TO_CHAR );
  2539. return;
  2540.     }
  2541.     if ( get_curr_str( ch ) <= 5 )
  2542.     {
  2543. send_to_char( "You are too weak to share your strength.nr", ch );
  2544. return;
  2545.     }
  2546.     af.type  = sn;
  2547.     af.duration  = level;
  2548.     af.location  = APPLY_STR;
  2549.     af.modifier  =  1 + ( level >= 20 ) + ( level >= 30 );
  2550.     af.bitvector = 0;
  2551.     affect_to_char( victim, &af );
  2552.     af.modifier  = -1 - ( level >= 20 ) - ( level >= 30 );
  2553.     affect_to_char( ch,     &af );
  2554.     act( "You share your strength with $N.", ch, NULL, victim, TO_CHAR );
  2555.     act( "$n shares $s strength with you.",  ch, NULL, victim, TO_VICT );
  2556.     return;
  2557. }
  2558. void spell_thought_shield ( int sn, int level, CHAR_DATA *ch, void *vo )
  2559. {
  2560.     CHAR_DATA  *victim = (CHAR_DATA *) vo;
  2561.     AFFECT_DATA af;
  2562.     if ( is_affected( victim, sn ) )
  2563.         return;
  2564.     af.type  = sn;
  2565.     af.duration  = level;
  2566.     af.location  = APPLY_AC;
  2567.     af.modifier  = -20;
  2568.     af.bitvector = 0;
  2569.     affect_to_char( victim, &af );
  2570.     send_to_char( "You have created a shield around yourself.nr", ch );
  2571.     return;
  2572. }
  2573. void spell_ultrablast ( int sn, int level, CHAR_DATA *ch, void *vo )
  2574. {
  2575.     CHAR_DATA *vch;
  2576.     CHAR_DATA *vch_next;
  2577.     int        dam;
  2578.     int        hpch;
  2579.     for ( vch = ch->in_room->people; vch; vch = vch_next )
  2580.     {
  2581.         vch_next = vch->next_in_room;
  2582. // if ( vch->deleted )
  2583. //     continue;
  2584. if ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) )
  2585. {
  2586.     hpch = UMAX( 10, ch->hit );
  2587.     dam  = number_range( hpch / 8+1, hpch / 4 );
  2588.     if ( saves_spell( level, vch ) )
  2589.         dam /= 2;
  2590.     damage( ch, vch, dam, sn );
  2591. }
  2592.     }
  2593.     return;
  2594. }
  2595. void spell_animate_dead( int sn, int level, CHAR_DATA *ch, void *vo )
  2596. {
  2597.     OBJ_DATA *vobj, *vobj_next;
  2598.     char buf[MAX_STRING_LENGTH];
  2599.     bool f = TRUE;
  2600.     for ( vobj = ch->in_room->contents; vobj; vobj = vobj_next )
  2601.     {
  2602.        vobj_next = vobj->next_content;
  2603.        /* Is the item a corpse?  (Note:  This may not be the best way to
  2604.           check...  This picks up all NPC corpses, including ones that reset
  2605.           on the zones... */
  2606.        if (vobj->item_type == ITEM_CORPSE_NPC)
  2607.           {
  2608.           /* Create a corpse mobile from a template */
  2609.           CHAR_DATA *undead = create_mobile(
  2610.              get_mob_index(MOB_VNUM_WALKING_DEAD) );
  2611.           /* Customize it */
  2612.          free_string( undead->short_descr );
  2613.        undead->short_descr = str_dup( vobj->short_descr );
  2614.           sprintf(buf, "%s slowly stumbles forward.nr", vobj->short_descr);
  2615.           free_string( undead->long_descr);
  2616.           undead->long_descr = str_dup( buf );
  2617.           /* (At this point, it looks like an undead corpse, and it would be
  2618.              possible to set the level of the corpse, it's HPs, etc., based
  2619.              on the caster.)
  2620.           */
  2621.           /* The original corpse is no more. */
  2622.           extract_obj( vobj );
  2623.           /* Place the fully formed corpse in the room */
  2624.           char_to_room( undead , ch->in_room );
  2625.           act("$p staggers to its feet.", undead, vobj, NULL, TO_ROOM);
  2626.           /* Try to charm it */
  2627.           spell_charm_person( sn, level, ch, undead );
  2628.           /* Yes, there was a corpse in this room */
  2629.           f = FALSE;
  2630.           }
  2631.     }
  2632.     /* Did we not even try to raise the dead? */
  2633.     if (f)
  2634.        act( "You carefully draw a pentagram around nothing, and nothing happens.",
  2635.           ch, NULL, NULL, TO_CHAR );
  2636. }