/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. In particular, you may not remove either of *
* these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
/***************************************************************************
* God Wars Mud copyright (C) 1994, 1995, 1996 by Richard Woolcock *
* *
* Legend of Chrystancia copyright (C) 1999, 2000, 2001 by Matthew Little *
* This mud is NOT to be copied in whole or in part, or to be run without *
* the permission of Matthew Little. Nobody else has permission to *
* authorise the use of this code. *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
/*
* Local functions.
*/
void say_spell args ((CHAR_DATA * ch, int sn));
void improve_spl args ((CHAR_DATA * ch, int dtype, int sn));
/*
* Improve ability at a certain spell type. KaVir.
*/
void improve_spl (CHAR_DATA * ch, int dtype, int sn)
{
char buf[MAX_INPUT_LENGTH];
char bufskill[MAX_INPUT_LENGTH];
char buftype[MAX_INPUT_LENGTH];
int dice1;
int dice2;
dice1 = number_percent ();
dice2 = number_percent ();
if (ch->in_room == NULL || IS_SET (ch->in_room->room_flags, ROOM_NO_TRAIN))
return;
if (dtype == 0)
sprintf (buftype, "#Ppurple#n");
else if (dtype == 1)
sprintf (buftype, "#rred#n");
else if (dtype == 2)
sprintf (buftype, "#bblue#n");
else if (dtype == 3)
sprintf (buftype, "#ggreen#n");
else if (dtype == 4)
sprintf (buftype, "#yyellow#n");
else
return;
if (ch->spl[dtype] >= 200 && !IS_CLASS (ch, CLASS_MAGE) && !(IS_CLASS (ch, CLASS_DROW)
&& IS_SET (ch->special, SPC_DROW_MAG)
&& (dtype == 0 || dtype == 1))
&& !(IS_CLASS (ch, CLASS_DROW) && IS_SET (ch->special, SPC_DROW_CLE)
&& (dtype == 2 || dtype == 3)))
return;
if (ch->spl[dtype] >= 240)
return;
if ((dice1 > (ch->spl[dtype]) || dice2 > (ch->spl[dtype])) || (dice1 >= 97 || dice2 >= 97)) ch->spl[dtype] += 1;
else return;
/*
if ((dice1 > ch->spl[dtype] || dice2 > ch->spl[dtype])
|| (dice1 == 100 || dice2 == 100))
ch->spl[dtype] += 1;
else
return;
*/
if (ch->spl[dtype] == 1)
sprintf (bufskill, "an apprentice of");
else if (ch->spl[dtype] == 26)
sprintf (bufskill, "a student at");
else if (ch->spl[dtype] == 51)
sprintf (bufskill, "a scholar at");
else if (ch->spl[dtype] == 76)
sprintf (bufskill, "a magus at");
else if (ch->spl[dtype] == 101)
sprintf (bufskill, "an adept at");
else if (ch->spl[dtype] == 126)
sprintf (bufskill, "a mage at");
else if (ch->spl[dtype] == 151)
sprintf (bufskill, "a warlock at");
else if (ch->spl[dtype] == 176)
sprintf (bufskill, "a master wizard at");
else if (ch->spl[dtype] == 200)
sprintf (bufskill, "a grand sorcerer at");
else if (ch->spl[dtype] == 240)
sprintf (bufskill, "the complete master of");
else
return;
sprintf (buf, "#wYou are now %s %s #wmagic#n.\n\r", bufskill, buftype);
send_to_char (buf, ch);
if (ch->spl[dtype] == 200)
{
ch->exp += 10000;
}
return;
}
bool is_obj (CHAR_DATA * ch)
{
OBJ_DATA *obj;
if ((obj = ch->pcdata->chobj) == NULL)
{
send_to_char ("Huh?\n\r", ch);
return FALSE;
}
if (obj->chobj == NULL || obj->chobj != ch)
{
send_to_char ("Huh?\n\r", ch);
return FALSE;
}
if (!IS_CLASS (ch, CLASS_DEMON) && !IS_SET (ch->special, SPC_CHAMPION))
{
send_to_char ("Huh?\n\r", ch);
return FALSE;
}
if (!IS_DEMPOWER (ch, DEM_MAGIC))
{
send_to_char ("You haven't been granted the gift of magic.\n\r", ch);
return FALSE;
}
return TRUE;
}
/*
* Lookup a skill by name.
*/
int skill_lookup (const char *name)
{
int sn;
for (sn = 0; sn < MAX_SKILL; sn++)
{
if (skill_table[sn].name == NULL)
break;
if (LOWER (name[0]) == LOWER (skill_table[sn].name[0])
&& !str_prefix (name, skill_table[sn].name))
return sn;
}
return -1;
}
/*
* Lookup a skill by slot number.
* Used for object loading.
*/
int slot_lookup (int slot)
{
extern bool fBootDb;
int sn;
if (slot <= 0)
return -1;
for (sn = 0; sn < MAX_SKILL; sn++)
{
if (slot == skill_table[sn].slot)
return sn;
}
if (fBootDb)
{
bug ("Slot_lookup: bad slot %d.", slot);
abort ();
}
return -1;
}
int sn_lookup (int sn)
{
int num;
if (sn <= 0 || sn > MAX_SKILL)
return 0;
num = skill_table[sn].slot;
return num;
}
/*
* Utter mystical words for an sn.
*/
void say_spell (CHAR_DATA * ch, int sn)
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
char colour[MAX_STRING_LENGTH];
/* CHAR_DATA *rch; */
char *pName;
char *gtype;
bool add_s;
int iSyl;
int length;
struct syl_type
{
char *old;
char *new;
};
static const struct syl_type syl_table[] = {
{" ", " "},
{"ar", "abra"},
{"au", "kada"},
{"bless", "fido"},
{"blind", "nose"},
{"bur", "mosa"},
{"cu", "judi"},
{"de", "oculo"},
{"en", "unso"},
{"light", "dies"},
{"lo", "hi"},
{"mor", "zak"},
{"move", "sido"},
{"ness", "lacri"},
{"ning", "illa"},
{"per", "duda"},
{"ra", "gru"},
{"re", "candus"},
{"son", "sabru"},
{"tect", "infra"},
{"tri", "cula"},
{"ven", "nofo"},
{"a", "c"}, {"b", "b"}, {"c", "q"}, {"d", "e"},
{"e", "z"}, {"f", "m"}, {"g", "o"}, {"h", "p"},
{"i", "u"}, {"j", "y"}, {"k", "t"}, {"l", "r"},
{"m", "w"}, {"n", "i"}, {"o", "a"}, {"p", "s"},
{"q", "d"}, {"r", "f"}, {"s", "g"}, {"t", "h"},
{"u", "j"}, {"v", "z"}, {"w", "x"}, {"x", "n"},
{"y", "l"}, {"z", "k"},
{"", ""}
};
buf[0] = '\0';
for (pName = skill_table[sn].name; *pName != '\0'; pName += length)
{
for (iSyl = 0; (length = strlen (syl_table[iSyl].old)) != 0; iSyl++)
{
if (!str_prefix (syl_table[iSyl].old, pName))
{
strcat (buf, syl_table[iSyl].new);
break;
}
}
if (length == 0)
length = 1;
}
sprintf (buf2, "$n utters the words, '%s'.", buf);
sprintf (buf, "$n utters the words, '%s'.", skill_table[sn].name);
if (IS_EXTRA (ch, EXTRA_OSWITCH))
{
gtype = "blade";
add_s = TRUE;
}
else if (IS_HEAD (ch, LOST_EYE_L) && IS_HEAD (ch, LOST_EYE_R))
{
gtype = "empty eye sockets";
add_s = FALSE;
}
else if (IS_HEAD (ch, LOST_EYE_L))
{
gtype = "right eye";
add_s = TRUE;
}
else if (IS_HEAD (ch, LOST_EYE_R))
{
gtype = "left eye";
add_s = TRUE;
}
else
{
gtype = "eyes";
add_s = FALSE;
}
if (skill_table[sn].target == 0)
{
sprintf (colour, "#P$n's %s glow%s bright purple for a moment.#n",
gtype, add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_ROOM);
sprintf (colour, "#PYour %s glow%s bright purple for a moment.#n",
gtype, add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_CHAR);
}
else if (skill_table[sn].target == 1)
{
sprintf (colour, "#r$n's %s glow%s bright red for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_ROOM);
sprintf (colour, "#rYour %s glow%s bright red for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_CHAR);
}
else if (skill_table[sn].target == 2)
{
sprintf (colour, "#b$n's %s glow%s bright blue for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_ROOM);
sprintf (colour, "#bYour %s glow%s bright blue for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_CHAR);
}
else if (skill_table[sn].target == 3)
{
sprintf (colour, "#g$n's %s glow%s bright green for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_ROOM);
sprintf (colour, "#gYour %s glow%s bright green for a moment.#n", gtype,
add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_CHAR);
}
else if (skill_table[sn].target == 4)
{
sprintf (colour, "#y$n's %s glow%s bright yellow for a moment.#n",
gtype, add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_ROOM);
sprintf (colour, "#yYour %s glow%s bright yellow for a moment.#n",
gtype, add_s ? "s" : "");
act (colour, ch, NULL, NULL, TO_CHAR);
}
return;
}
/*
* Compute a saving throw.
* Negative apply's make saving throw better.
*/
bool saves_spell (int level, CHAR_DATA * victim)
{
int save;
int tsave;
if (!IS_NPC (victim))
{
tsave =
(victim->spl[0] + victim->spl[1] + victim->spl[2] + victim->spl[3] +
victim->spl[4]) * 0.05;
save = 50 + (tsave - level - victim->saving_throw) * 5;
}
else
save = 50 + (victim->level - level - victim->saving_throw) * 5;
save = URANGE (15, save, 85);
return number_percent () < save;
}
/*
* The kludgy global is for spells who want more stuff from command line.
*/
char *target_name;
void do_cast (CHAR_DATA * ch, char *argument)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
OBJ_DATA *obj;
void *vo;
int mana;
int sn;
int chance;
chance = number_percent ();
if (chance > 40 && IS_CLASS (ch, CLASS_DEMON)
&& IS_SET (ch->warp, WARP_STUPID))
{
stc ("You are too stupid to cast spells!\n\r", ch);
return;
}
/*
* Switched NPC's can cast spells, but others can't.
*/
if (IS_NPC (ch) && ch->desc == NULL)
return;
/* Polymorphed players cannot cast spells */
if (!IS_NPC (ch) && IS_AFFECTED (ch, AFF_POLYMORPH) &&
!IS_VAMPAFF (ch, VAM_DISGUISED) && !IS_POLYAFF (ch, POLY_ZULO)
&& !IS_POLYAFF (ch, POLY_SPIDERFORM) && !IS_POLYAFF (ch, POLY_DRAGON)
&& !IS_SET (ch->flag2, VAMP_OBJMASK) && !IS_POLYAFF (ch, POLY_PFORM))
{
if (!is_obj (ch))
{
send_to_char ("You cannot cast spells in this form.\n\r", ch);
return;
}
}
if ( IS_HEAD(ch, LOST_TONGUE) )
{
send_to_char( "You can't cast without a tongue!\n\r", ch );
return;
}
if ( IS_EXTRA(ch, GAGGED) )
{
send_to_char( "You can't cast with a gag on!\n\r", ch );
return;
}
if (ch->in_room != NULL && IS_SET(ch->in_room->added_flags, ROOM2_SILENCE))
{
send_to_char( "Your words make no sound!\n\r", ch );
return;
}
if (IS_ITEMAFF (ch, ITEMA_REFLECT))
{
send_to_char ("You are unable to focus your spell.\n\r", ch);
return;
}
target_name = one_argument (argument, arg1);
one_argument (target_name, arg2);
if (arg1[0] == '\0')
{
send_to_char ("Cast which what where?\n\r", ch);
return;
}
if (IS_CLASS (ch, CLASS_HIGHLANDER) && !IS_IMMORTAL (ch))
{
if ((skill_lookup (arg1) == skill_lookup ("locate"))
|| (skill_lookup (arg1) == skill_lookup ("repair"))
|| (skill_lookup (arg1) == skill_lookup ("quest"))
|| (skill_lookup (arg1) == skill_lookup ("portal"))
|| (skill_lookup (arg1) == skill_lookup ("spellproof"))
|| (skill_lookup (arg1) == skill_lookup ("resistance"))
|| (skill_lookup (arg1) == skill_lookup ("preserve"))
|| (skill_lookup (arg1) == skill_lookup ("mend"))
|| (skill_lookup (arg1) == skill_lookup ("clot"))
|| (skill_lookup (arg1) == skill_lookup ("regenerate"))
|| (skill_lookup (arg1) == skill_lookup ("teleport"))
|| (skill_lookup (arg1) == skill_lookup ("dispel magic")))
{
stc ("You call upon your ancestors.\n\r", ch);
}
else
{
stc ("You are NOT a finger-waggler.\n\r", ch);
return;
}
}
if ((sn = skill_lookup (arg1)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (skill_lookup (arg1) == skill_lookup ("backstab")
|| skill_lookup (arg1) == skill_lookup ("disarm")
|| skill_lookup (arg1) == skill_lookup ("berserk")
|| skill_lookup (arg1) == skill_lookup ("hide")
|| skill_lookup (arg1) == skill_lookup ("hurl")
|| skill_lookup (arg1) == skill_lookup ("kick")
|| skill_lookup (arg1) == skill_lookup ("peek")
|| skill_lookup (arg1) == skill_lookup ("pick lock")
|| skill_lookup (arg1) == skill_lookup ("rescue")
|| skill_lookup (arg1) == skill_lookup ("sneak")
|| skill_lookup (arg1) == skill_lookup ("steal")
|| skill_lookup (arg1) == skill_lookup ("punch")
|| skill_lookup (arg1) == skill_lookup ("elbow")
|| skill_lookup (arg1) == skill_lookup ("headbutt")
|| skill_lookup (arg1) == skill_lookup ("sweep")
|| skill_lookup (arg1) == skill_lookup ("knee")
|| skill_lookup (arg1) == skill_lookup ("fastdraw")
|| skill_lookup (arg1) == skill_lookup ("track"))
{
send_to_char ("Thats a #rSKILL#n, not a #ySpell#n.\n\r", ch);
return;
}
if (ch->position < skill_table[sn].minimum_position)
{
if (!IS_NPC (ch) && !IS_CLASS (ch, CLASS_VAMPIRE)
&& IS_VAMPAFF (ch, VAM_CELERITY))
{
if (ch->move < 25)
{
send_to_char ("You can't concentrate enough.\n\r", ch);
return;
}
ch->move = ch->move - 25;
}
else
{
if (ch->move < 50)
{
send_to_char ("You can't concentrate enough.\n\r", ch);
return;
}
ch->move = ch->move - 50;
}
}
mana =
IS_NPC (ch) ? 0 : UMAX (skill_table[sn].min_mana,
100 / (2 + (ch->level * 12) -
skill_table[sn].skill_level));
if (IS_CLASS (ch, CLASS_DRAGON)
&& IS_SET (ch->pcdata->dragonaff, DRA_MAGIC))
mana = 1;
/*
* Locate targets.
*/
victim = NULL;
obj = NULL;
vo = NULL;
switch (skill_table[sn].target)
{
default:
bug ("Do_cast: bad target for sn %d.", sn);
return;
case TAR_IGNORE:
if (!IS_NPC (ch))
send_purplespell (ch);
break;
case TAR_CHAR_OFFENSIVE:
if (arg2[0] == '\0')
{
if ((victim = ch->fighting) == NULL)
{
send_to_char ("Cast the spell on whom?\n\r", ch);
return;
}
}
else
{
if ((victim = get_char_room (ch, arg2)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
}
send_redspell (ch);
if (victim != ch && !IS_NPC (victim))
send_redspell (victim);
if (ch == victim)
send_to_char ("Cast this on yourself? Ok...\n\r", ch);
if (IS_ITEMAFF (victim, ITEMA_REFLECT))
{
send_to_char ("You are unable to focus your spell upon them.\n\r",
ch);
return;
}
if (!IS_NPC (victim) && (!CAN_PK (ch) || !CAN_PK (victim))
&& (ch != victim))
{
send_to_char ("You are unable to affect them.\n\r", ch);
return;
}
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_DROW))
{
if (ch == victim)
{
send_to_char ("You lower your magical resistance....\n\r", ch);
}
else if (number_percent () <= victim->pcdata->stats[DROW_MAGIC])
{
send_to_char ("Your spell does not affect them.\n\r", ch);
return;
}
}
if (!IS_NPC (ch))
{
if (IS_AFFECTED (ch, AFF_CHARM) && ch->master == victim)
{
send_to_char ("You can't do that on your own follower.\n\r", ch);
return;
}
}
if (IS_CLASS (victim, CLASS_HIGHLANDER) && (victim != ch))
{
if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
{
if (victim->quickening[0] >= 1)
{
victim->quickening[0] -= 1;
stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
victim);
return;
}
}
}
if (is_safe (ch, victim))
return;
if (IS_SET (ch->extra2, AURA_NO_MAGIC))
do_auranomagic (ch, "");
if (IS_AFFECTED (ch, AFF_STEELSHIELD) && IS_CLASS (ch, CLASS_VAMPIRE))
do_majesty (ch, "");
if (IS_AFFECTED (ch, AFF_STEELSHIELD) && IS_CLASS (ch, CLASS_FAE))
do_grandeur (ch, "");;
vo = (void *) victim;
break;
case TAR_CHAR_DEFENSIVE:
if (arg2[0] == '\0')
{
victim = ch;
}
else
{
if ((victim = get_char_room (ch, arg2)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
}
if (IS_ITEMAFF (victim, ITEMA_REFLECT))
{
send_to_char ("You are unable to focus your spell upon them.\n\r",
ch);
return;
}
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_DROW))
{
if (ch == victim)
{
send_to_char ("You lower your magical resistance....\n\r", ch);
}
else if (number_percent () <= victim->pcdata->stats[DROW_MAGIC])
{
send_to_char ("Your spell does not affect them.\n\r", ch);
return;
}
}
if (IS_CLASS (victim, CLASS_HIGHLANDER) && (victim != ch))
{
if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
{
if (victim->quickening[0] >= 1)
{
victim->quickening[0] -= 1;
stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
victim);
return;
}
}
}
send_bluespell (ch);
if (victim != ch && !IS_NPC (victim))
send_bluespell (victim);
vo = (void *) victim;
break;
case TAR_CHAR_SELF:
if (arg2[0] != '\0' && !is_name (arg2, ch->name))
{
send_to_char ("You cannot cast this spell on another.\n\r", ch);
return;
}
send_greenspell (ch);
vo = (void *) ch;
break;
case TAR_OBJ_INV:
if (skill_lookup (arg1) != skill_lookup ("regenerate"))
{
if (arg2[0] == '\0')
{
send_to_char ("What should the spell be cast upon?\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg2)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
}
send_yellowspell (ch);
vo = (void *) obj;
break;
}
if (!IS_NPC (ch) && ch->mana < mana)
{
send_to_char ("You don't have enough mana.\n\r", ch);
return;
}
if (str_cmp (skill_table[sn].name, "ventriloquate"))
say_spell (ch, sn);
if (IS_CLASS (ch, CLASS_DROW) && IS_SET (ch->special, SPC_DROW_MAG))
WAIT_STATE (ch, skill_table[sn].beats / 2);
else if (IS_CLASS (ch, CLASS_MAGE) && ch->spheres[MTIM] == 0)
WAIT_STATE (ch, skill_table[sn].beats);
else if (IS_CLASS (ch, CLASS_MAGE))
{
if (ch->spheres[MTIM] > 0)
{
WAIT_STATE (ch, (skill_table[sn].beats / (ch->spheres[MTIM] + 1)));
send_to_char ("You sidestep time.\n\r", ch);
}
}
else if (!IS_IMMORTAL (ch))
//testing && !IS_CLASS (ch, CLASS_MAGE) && (!IS_SET(ch->special, SPC_DROW_MAG)))
WAIT_STATE (ch, skill_table[sn].beats);
if (!IS_NPC (ch) && number_percent () > ch->pcdata->learned[sn])
{
send_to_char ("You lost your concentration.\n\r", ch);
ch->mana -= mana / 2;
improve_spl (ch, skill_table[sn].target, sn);
}
else
{
ch->mana -= mana;
/* Check players ability at spell type for spell power...KaVir */
if (IS_NPC (ch))
(*skill_table[sn].spell_fun) (sn, ch->level, ch, vo);
else if (!IS_CLASS (ch, CLASS_MAGE))
{
(*skill_table[sn].spell_fun) (sn,
(ch->spl[skill_table[sn].target] *
0.25), ch, vo);
improve_spl (ch, skill_table[sn].target, sn);
}
else if (IS_CLASS (ch, CLASS_MAGE))
{
if (ch->spheres[MENT] >= 1)
{
(*skill_table[sn].spell_fun) (sn,
(ch->
spl[skill_table[sn].target] *
(.25 +
(ch->spheres[MENT] * .1))), ch,
vo);
improve_spl (ch, skill_table[sn].target, sn);
}
else
{
(*skill_table[sn].spell_fun) (sn,
(ch->
spl[skill_table[sn].target] *
0.25), ch, vo);
improve_spl (ch, skill_table[sn].target, sn);
}
}
}
if (skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim != ch
&& victim->master != ch)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
for (vch = ch->in_room->people; vch; vch = vch_next)
{
vch_next = vch->next_in_room;
if (victim == vch && victim->fighting == NULL)
{
multi_hit (victim, ch, TYPE_UNDEFINED);
break;
}
}
}
return;
}
/*
* Cast spells at targets using a magical object.
*/
void obj_cast_spell (int sn, int level, CHAR_DATA * ch, CHAR_DATA * victim,
OBJ_DATA * obj)
{
void *vo;
if (sn <= 0)
return;
if (IS_NPC (ch))
return;
if (IS_CLASS (ch, CLASS_HIGHLANDER))
return;
if (sn >= MAX_SKILL || skill_table[sn].spell_fun == 0)
{
bug ("Obj_cast_spell: bad sn %d.", sn);
return;
}
switch (skill_table[sn].target)
{
default:
bug ("Obj_cast_spell: bad target for sn %d.", sn);
return;
case TAR_IGNORE:
vo = NULL;
break;
case TAR_CHAR_OFFENSIVE:
if (victim == NULL)
victim = ch->fighting;
if (victim == NULL)
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
if (IS_SET (ch->extra2, AURA_NO_MAGIC))
do_auranomagic (ch, "");
if (IS_AFFECTED (ch, AFF_STEELSHIELD) && IS_CLASS (ch, CLASS_VAMPIRE))
do_majesty (ch, "");
if (IS_AFFECTED (ch, AFF_STEELSHIELD) && IS_CLASS (ch, CLASS_FAE))
do_grandeur (ch, "");
vo = (void *) victim;
break;
case TAR_CHAR_DEFENSIVE:
if (victim == NULL)
victim = ch;
vo = (void *) victim;
break;
case TAR_CHAR_SELF:
vo = (void *) ch;
break;
case TAR_OBJ_INV:
if (obj == NULL)
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (obj->item_type == ITEM_PORTAL || obj->item_type == ITEM_WALL
|| obj->item_type == ITEM_FOUNTAIN)
{
stc ("You cant do that!\n\r", ch);
return;
}
vo = (void *) obj;
break;
}
target_name = "";
(*skill_table[sn].spell_fun) (sn, level, ch, vo);
if (skill_table[sn].target == TAR_CHAR_OFFENSIVE && victim != ch
&& victim->master != ch)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
for (vch = ch->in_room->people; vch; vch = vch_next)
{
vch_next = vch->next_in_room;
if (victim == vch && victim->fighting == NULL)
{
multi_hit (victim, ch, TYPE_UNDEFINED);
break;
}
}
}
return;
}
/*
* Spell functions.
*/
void spell_acid_blast (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hp;
if (IS_ITEMAFF (victim, ITEMA_ACIDSHIELD))
return;
dam = dice (level, 6);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_ACID))
victim->hit = hp;
return;
}
void spell_armor (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 24;
af.modifier = -20;
af.location = APPLY_AC;
af.bitvector = 0;
affect_to_char (victim, &af);
act ("$n is shrouded in a suit of translucent glowing armor.", victim,
NULL, NULL, TO_ROOM);
send_to_char
("You are shrouded in a suit of translucent glowing armor.\n\r",
victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_bless (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 6 + level;
af.location = APPLY_HITROLL;
af.modifier = level / 8;
af.bitvector = 0;
affect_to_char (victim, &af);
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level / 8;
affect_to_char (victim, &af);
act ("$n is blessed.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You feel righteous.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_spiritkiss (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 24;
af.location = APPLY_HITROLL;
af.modifier = level;
af.bitvector = 0;
affect_to_char (victim, &af);
af.type = sn;
af.duration = 24;
af.location = APPLY_DAMROLL;
af.modifier = level;
af.bitvector = 0;
affect_to_char (victim, &af);
af.type = sn;
af.duration = 24;
af.location = APPLY_HIT;
af.modifier = 15 * level;
af.bitvector = 0;
affect_to_char (victim, &af);
af.type = sn;
af.duration = 24;
af.location = APPLY_MANA;
af.modifier = 20 * level;
af.bitvector = 0;
affect_to_char (victim, &af);
af.type = sn;
af.duration = 24;
af.location = APPLY_MOVE;
af.modifier = 10 * level;
af.bitvector = 0;
affect_to_char (victim, &af);
af.location = APPLY_SAVING_SPELL;
af.duration = 24;
af.modifier = 0 - level * 2;
affect_to_char (victim, &af);
act ("$n is filled with spiritual power.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You are blessed by the spirits.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_lunasblessing (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 2 * level;
af.location = APPLY_HITROLL;
af.modifier = level * 2;
af.bitvector = 0;
affect_to_char (victim, &af);
af.type = sn;
af.duration = 2 * level;
af.location = APPLY_DAMROLL;
af.modifier = level * 2;
af.bitvector = 0;
affect_to_char (victim, &af);
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level / 2;
affect_to_char (victim, &af);
act ("$n is filled with Luna's Blessing.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You feel Luna's Blessing engulf you.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_greaterbless( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) ) return;
af.type = sn;
af.duration = 2*level;
af.location = APPLY_HITROLL;
af.modifier = 100;
af.bitvector = 0;
affect_to_char( victim, &af );
af.type = sn;
af.duration = 2*level;
af.location = APPLY_DAMROLL;
af.modifier = 100;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level /2;
affect_to_char( victim, &af );
act( "#WA bright #wwhite #Wshield surrounds $n as they are filled with a greater bless.#n", victim, NULL, NULL, TO_ROOM );
send_to_char( "A bright #wwhite#n shield surrounds you as you're filled with a greater bless.#n\n\r", victim );
if ( ch != victim )
send_to_char( "Ok.\n\r", ch );
return;
}
void spell_blindness (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_INPUT_LENGTH];
if (IS_AFFECTED (victim, AFF_BLIND) || saves_spell (level, victim))
return;
af.type = sn;
af.location = APPLY_HITROLL;
af.modifier = -4;
af.duration = 1 + level;
af.bitvector = AFF_BLIND;
affect_to_char (victim, &af);
send_to_char ("You are blinded!\n\r", victim);
if (!IS_NPC (victim))
sprintf (buf, "%s is blinded!\n\r", victim->name);
else
sprintf (buf, "%s is blinded!\n\r", victim->short_descr);
send_to_char (buf, ch);
return;
}
void spell_burning_hands (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
4,
6, 8, 10, 12, 14, 17, 20, 23, 26, 29,
29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
50, 60, 70, 80, 90, 100, 125, 150, 175, 200
};
int dam;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_HEAT))
dam /= 1.5;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE))
{
damage (ch, victim, (dam * 2), sn);
}
else
damage (ch, victim, dam, sn);
return;
}
void spell_call_lightning (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
int dam;
if (!IS_OUTSIDE (ch))
{
send_to_char ("You must be out of doors.\n\r", ch);
return;
}
if (weather_info.sky < SKY_RAINING)
{
send_to_char ("You need bad weather.\n\r", ch);
return;
}
dam = dice (level / 2, 8);
send_to_char ("God's lightning strikes your foes!\n\r", ch);
act ("$n calls God's lightning to strike $s foes!", ch, NULL, NULL,
TO_ROOM);
for (vch = char_list; vch != NULL; vch = vch_next)
{
vch_next = vch->next;
if (vch->in_room == NULL)
continue;
if (vch->in_room == ch->in_room)
{
if (vch != ch && (IS_NPC (ch) ? !IS_NPC (vch) : IS_NPC (vch)))
{
if (!IS_NPC (vch) && IS_IMMUNE (vch, IMM_LIGHTNING))
dam /= 1.5;
if (saves_spell (level, vch))
dam /= 2;
damage (ch, vch, dam, sn);
}
continue;
}
if (vch->in_room->area == ch->in_room->area && IS_OUTSIDE (vch)
&& IS_AWAKE (vch))
send_to_char ("Lightning flashes in the sky.\n\r", vch);
}
return;
}
void spell_cause_light (int sn, int level, CHAR_DATA * ch, void *vo)
{
damage (ch, (CHAR_DATA *) vo, dice (1, 8) + level / 3, sn);
return;
}
void spell_cause_critical (int sn, int level, CHAR_DATA * ch, void *vo)
{
damage (ch, (CHAR_DATA *) vo, dice (3, 8) + level - 6, sn);
return;
}
void spell_cause_serious (int sn, int level, CHAR_DATA * ch, void *vo)
{
damage (ch, (CHAR_DATA *) vo, dice (2, 8) + level / 2, sn);
return;
}
void spell_change_sex (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
return;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 10 * level;
af.location = APPLY_SEX;
do
{
af.modifier = number_range (0, 2) - victim->sex;
}
while (af.modifier == 0);
af.bitvector = 0;
affect_to_char (victim, &af);
send_to_char ("You feel different.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_charm_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (victim == ch)
{
send_to_char ("You like yourself even better!\n\r", ch);
return;
}
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_CHARM))
{
send_to_char ("You failed.\n\r", ch);
return;
}
/* I don't want people charming ghosts and stuff - KaVir */
if (IS_NPC (victim) && IS_AFFECTED (victim, AFF_ETHEREAL))
{
send_to_char ("You failed.\n\r", ch);
return;
}
if (IS_IMMORTAL (victim))
{
send_to_char ("You can cast puny mortal magic on immortals!\n\r", ch);
return;
}
if (IS_AFFECTED (victim, AFF_CHARM) || IS_AFFECTED (ch, AFF_CHARM)
|| level < victim->level || saves_spell (level, victim))
return;
if (victim->master)
stop_follower (victim);
add_follower (victim, ch);
af.type = sn;
af.duration = number_fuzzy (level / 4);
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char (victim, &af);
act ("Isn't $n just so nice?", ch, NULL, victim, TO_VICT);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_chill_touch (int sn, int level, CHAR_DATA * ch, void *vo)
{
bool no_dam = FALSE;
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
9,
10, 10, 10, 11, 11, 12, 12, 13, 13, 13,
14, 14, 14, 15, 15, 15, 16, 16, 16, 17,
17, 17, 18, 18, 18, 19, 19, 19, 20, 20,
20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
24, 24, 24, 25, 25, 25, 26, 26, 26, 27,
30, 40, 50, 60, 70, 80, 90, 100, 110, 120
};
AFFECT_DATA af;
int dam;
int hp;
if (IS_ITEMAFF (victim, ITEMA_ICESHIELD))
return;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_COLD))
no_dam = TRUE;
if (!no_dam
&& (!saves_spell (level, victim) || IS_NPC (victim)
|| !IS_CLASS (victim, CLASS_VAMPIRE)))
{
af.type = sn;
af.duration = 6;
af.location = APPLY_STR;
af.modifier = -1;
af.bitvector = 0;
affect_join (victim, &af);
}
else
{
dam /= 2;
}
hp = victim->hit;
damage (ch, victim, dam, sn);
if (no_dam)
victim->hit = hp;
return;
}
void spell_colour_spray (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
10,
15, 15, 15, 15, 15, 20, 20, 20, 20, 20,
30, 35, 40, 45, 50, 55, 55, 55, 56, 57,
58, 58, 59, 60, 61, 61, 62, 63, 64, 64,
65, 66, 67, 67, 68, 69, 70, 70, 71, 72,
73, 73, 74, 75, 76, 76, 77, 78, 79, 79,
85, 95, 110, 125, 150, 175, 200, 250, 300, 350
};
int dam;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
return;
}
void spell_continual_light (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *light;
light = create_object (get_obj_index (OBJ_VNUM_LIGHT_BALL), 0);
obj_to_room (light, ch->in_room);
act ("$n twiddles $s thumbs and $p appears.", ch, light, NULL, TO_ROOM);
act ("You twiddle your thumbs and $p appears.", ch, light, NULL, TO_CHAR);
return;
}
void spell_control_weather (int sn, int level, CHAR_DATA * ch, void *vo)
{
if (!str_cmp (target_name, "better"))
weather_info.change += dice (level / 3, 4);
else if (!str_cmp (target_name, "worse"))
weather_info.change -= dice (level / 3, 4);
else
send_to_char ("Do you want it to get better or worse?\n\r", ch);
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_create_food (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *mushroom;
mushroom = create_object (get_obj_index (OBJ_VNUM_MUSHROOM), 0);
mushroom->value[0] = 5 + level;
mushroom->timer = 20;
obj_to_room (mushroom, ch->in_room);
act ("$p suddenly appears.", ch, mushroom, NULL, TO_ROOM);
act ("$p suddenly appears.", ch, mushroom, NULL, TO_CHAR);
return;
}
void spell_create_spring (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *spring;
if (!IS_NPC (ch) && IS_CLASS (ch, CLASS_VAMPIRE))
spring = create_object (get_obj_index (OBJ_VNUM_BLOOD_SPRING), 0);
else
spring = create_object (get_obj_index (OBJ_VNUM_SPRING), 0);
spring->timer = level;
obj_to_room (spring, ch->in_room);
act ("$p flows from the ground.", ch, spring, NULL, TO_ROOM);
act ("$p flows from the ground.", ch, spring, NULL, TO_CHAR);
return;
}
void spell_create_water (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
int water;
if (obj->item_type != ITEM_DRINK_CON)
{
send_to_char ("It is unable to hold water.\n\r", ch);
return;
}
if (obj->value[2] != LIQ_WATER && obj->value[1] != 0)
{
send_to_char ("It contains some other liquid.\n\r", ch);
return;
}
water =
UMIN (level * (weather_info.sky >= SKY_RAINING ? 4 : 2),
obj->value[0] - obj->value[1]);
if (water > 0)
{
obj->value[2] = LIQ_WATER;
obj->value[1] += water;
if (!is_name ("water", obj->name))
{
char buf[MAX_STRING_LENGTH];
sprintf (buf, "%s water", obj->name);
free_string (obj->name);
obj->name = str_dup (buf);
}
act ("$p is filled.", ch, obj, NULL, TO_CHAR);
}
return;
}
void spell_cure_blindness (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!is_affected (victim, gsn_blindness))
return;
affect_strip (victim, gsn_blindness);
send_to_char ("Your vision returns!\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_cure_critical (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
if (ch != victim && IS_NEWBIE(ch)) return;
heal = dice (3, 8) + level - 6;
victim->hit = UMIN (victim->hit + heal, victim->max_hit);
update_pos (victim);
send_to_char ("You feel better!\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_cure_light (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
if (ch != victim && IS_NEWBIE(ch)) return;
heal = dice (1, 8) + level / 3;
victim->hit = UMIN (victim->hit + heal, victim->max_hit);
update_pos (victim);
send_to_char ("You feel better!\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_cure_poison (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (is_affected (victim, gsn_poison))
{
affect_strip (victim, gsn_poison);
act ("$N looks better.", ch, NULL, victim, TO_NOTVICT);
send_to_char ("A warm feeling runs through your body.\n\r", victim);
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
}
return;
}
void spell_cure_serious (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
if (ch != victim && IS_NEWBIE(ch)) return;
heal = dice (2, 8) + level / 2;
victim->hit = UMIN (victim->hit + heal, victim->max_hit);
update_pos (victim);
send_to_char ("You feel better!\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_curse (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (ch != victim && IS_NEWBIE(ch)) return;
if (IS_AFFECTED (victim, AFF_CURSE) || saves_spell (level, victim))
return;
af.type = sn;
af.duration = 4 * level;
af.location = APPLY_HITROLL;
af.modifier = -1;
af.bitvector = AFF_CURSE;
affect_to_char (victim, &af);
af.location = APPLY_SAVING_SPELL;
af.modifier = 1;
affect_to_char (victim, &af);
send_to_char ("You feel unclean.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_detect_evil (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_DETECT_EVIL))
return;
af.type = sn;
af.duration = level;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_DETECT_EVIL;
affect_to_char (victim, &af);
send_to_char ("Your eyes tingle.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_detect_hidden (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_DETECT_HIDDEN))
return;
af.type = sn;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_HIDDEN;
affect_to_char (victim, &af);
send_to_char ("Your awareness improves.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_detect_invis (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_DETECT_INVIS))
return;
af.type = sn;
af.duration = level;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_DETECT_INVIS;
affect_to_char (victim, &af);
send_to_char ("Your eyes tingle.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_detect_magic (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_DETECT_MAGIC))
return;
af.type = sn;
af.duration = level;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_DETECT_MAGIC;
affect_to_char (victim, &af);
send_to_char ("Your eyes tingle.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_detect_poison (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if (obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD)
{
if (obj->value[3] != 0)
send_to_char ("You smell poisonous fumes.\n\r", ch);
else
send_to_char ("It looks very delicious.\n\r", ch);
}
else
{
send_to_char ("It doesn't look poisoned.\n\r", ch);
}
return;
}
/* New Dispel Good Spell */
void spell_dispel_good (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (!IS_NPC (ch) && IS_GOOD (ch))
victim = ch;
if (IS_EVIL (victim))
{
act ("Satan protects $N.", ch, NULL, victim, TO_ROOM);
return;
}
if (IS_NEUTRAL (victim))
{
act ("$N does not seem to be affected.", ch, NULL, victim, TO_CHAR);
return;
}
dam = dice (level, 35);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_dispel_evil (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (!IS_NPC (ch) && IS_EVIL (ch))
victim = ch;
if (IS_GOOD (victim))
{
act ("God protects $N.", ch, NULL, victim, TO_ROOM);
return;
}
if (IS_NEUTRAL (victim))
{
act ("$N does not seem to be affected.", ch, NULL, victim, TO_CHAR);
return;
}
dam = dice (level, 35);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_dispel_magic (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
bool dark = FALSE;
int chspell;
int vchspell;
chspell = (ch->spl[0] + ch->spl[1] + ch->spl[2] + ch->spl[3] + ch->spl[4]);
vchspell =
(victim->spl[0] + victim->spl[1] + victim->spl[2] + victim->spl[3] +
victim->spl[4]);
if (victim != ch && IS_CLASS (victim, CLASS_MAGE) && chspell < vchspell && !WORN_ARTIFACT (ch, ARTI_EMPERORS_BLADE))
{
stc ("Their Magic is too powerful to dispel\n\r", ch);
return;
}
if (victim != ch && (saves_spell (level, victim) || level < victim->level))
{
send_to_char ("You failed.\n\r", ch);
return;
}
if (IS_SET (victim->garou1, GAROU_WHELP1)
&& IS_SET (victim->garou1, GAROU_WHELP2))
{
REMOVE_BIT (victim->garou1, GAROU_WHELP1);
REMOVE_BIT (victim->garou1, GAROU_WHELP2);
victim->max_hit = victim->max_hit + 3000;
}
if (IS_SET (victim->flag2, AFF_TOTALBLIND))
{
REMOVE_BIT (victim->flag2, AFF_TOTALBLIND);
stc ("You can see again!\n\r", victim);
}
if (IS_SET (victim->monkstuff, MONK_DEATH))
REMOVE_BIT (victim->monkstuff, MONK_DEATH);
if (!(victim->affected))
{
send_to_char ("Nothing happens.\n\r", ch);
return;
}
if (IS_AFFECTED (victim, AFF_DARKNESS))
dark = TRUE;
while (victim->affected)
affect_remove (victim, victim->affected);
if (dark == TRUE)
REMOVE_BIT (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
if (ch == victim)
{
act ("You remove all magical affects from yourself.", ch, NULL, NULL,
TO_CHAR);
act ("$n has removed all magical affects from $mself.", ch, NULL, NULL,
TO_ROOM);
}
else
{
act ("You remove all magical affects from $N.", ch, NULL, victim,
TO_CHAR);
act ("$n has removed all magical affects from $N.", ch, NULL, victim,
TO_NOTVICT);
act ("$n has removed all magical affects from you.", ch, NULL, victim,
TO_VICT);
}
return;
}
void spell_earthquake (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
send_to_char ("The earth trembles beneath your feet!\n\r", ch);
act ("$n makes the earth tremble and shiver.", ch, NULL, NULL, TO_ROOM);
for (vch = char_list; vch != NULL; vch = vch_next)
{
vch_next = vch->next;
if (vch->in_room == NULL)
continue;
if (vch->in_room == ch->in_room)
{
if (vch != ch && (IS_NPC (ch) ? !IS_NPC (vch) : IS_NPC (vch)))
damage (ch, vch, level + dice (2, 8), sn);
continue;
}
if (vch->in_room->area == ch->in_room->area)
send_to_char ("The earth trembles and shivers.\n\r", vch);
}
return;
}
void spell_enchant_weapon (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA *paf;
if (obj->item_type != ITEM_WEAPON || IS_SET (obj->quest, QUEST_ENCHANTED)
|| IS_SET (obj->quest, QUEST_ARTIFACT) || obj->chobj != NULL)
{
send_to_char ("You are unable to enchant this weapon.\n\r", ch);
return;
}
if (affect_free == NULL)
{
paf = alloc_perm (sizeof (*paf));
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
/*
paf->type = 0;
*/
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = level / 5;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if (affect_free == NULL)
{
paf = alloc_perm (sizeof (*paf));
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
/*
paf->type = -1;
*/
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = level / 10;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if (IS_GOOD (ch))
{
SET_BIT (obj->extra_flags, ITEM_ANTI_EVIL);
SET_BIT (obj->quest, QUEST_ENCHANTED);
act ("$p glows blue.", ch, obj, NULL, TO_CHAR);
act ("$p glows blue.", ch, obj, NULL, TO_ROOM);
}
else if (IS_EVIL (ch))
{
SET_BIT (obj->extra_flags, ITEM_ANTI_GOOD);
SET_BIT (obj->quest, QUEST_ENCHANTED);
act ("$p glows red.", ch, obj, NULL, TO_CHAR);
act ("$p glows red.", ch, obj, NULL, TO_ROOM);
}
else
{
SET_BIT (obj->extra_flags, ITEM_ANTI_EVIL);
SET_BIT (obj->extra_flags, ITEM_ANTI_GOOD);
SET_BIT (obj->quest, QUEST_ENCHANTED);
act ("$p glows yellow.", ch, obj, NULL, TO_CHAR);
act ("$p glows yellow.", ch, obj, NULL, TO_ROOM);
}
return;
}
/*
* Drain XP, MANA, HP.
* Caster gains HP.
*/
void spell_energy_drain (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (saves_spell (level, victim))
return;
if (!IS_HERO (ch))
ch->alignment = UMAX (-1000, ch->alignment - 200);
if (victim->level <= 2)
{
dam = ch->hit + 1;
}
else
{
dam = dice (1, level);
if (IS_NPC (victim))
{
victim->mana /= 2;
victim->move /= 2;
ch->hit += dam;
if (ch->hit > (2 * ch->max_hit))
ch->hit = (2 * ch->max_hit);
}
}
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_DRAIN))
dam /= 1.5;
damage (ch, victim, dam, sn);
if (!IS_NPC (ch) && ch != victim)
do_beastlike (ch, "");
return;
}
void spell_fireball (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
20,
20, 20, 20, 20, 20, 25, 25, 25, 25, 25,
30, 30, 30, 30, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
150, 200, 250, 300, 400, 500, 650, 750, 850, 1000
};
int dam;
int hp;
if (IS_ITEMAFF (victim, ITEMA_FIRESHIELD))
return;
if (WORN_ARTIFACT (victim, ARTI_DEMONS_HEART))
return;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE))
{
damage (ch, victim, (dam * 2), sn);
hp = ((hp - victim->hit) / 2) + victim->hit;
}
else
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_HEAT))
victim->hit = hp;
return;
}
void spell_flamestrike (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (IS_ITEMAFF (victim, ITEMA_FIRESHIELD))
return;
if (WORN_ARTIFACT (victim, ARTI_DEMONS_HEART))
return;
dam = dice (6, 8);
if (saves_spell (level, victim))
dam /= 2;
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_HEAT))
dam /= 1.5;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE))
{
damage (ch, victim, (dam * 2), sn);
}
else
damage (ch, victim, dam, sn);
return;
}
void spell_faerie_fire (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_FAERIE_FIRE))
return;
af.type = sn;
af.duration = level;
af.location = APPLY_AC;
af.modifier = 2 * level;
af.bitvector = AFF_FAERIE_FIRE;
affect_to_char (victim, &af);
send_to_char ("You are surrounded by a pink outline.\n\r", victim);
act ("$n is surrounded by a pink outline.", victim, NULL, NULL, TO_ROOM);
return;
}
void spell_faerie_fog (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *ich;
act ("$n conjures a cloud of purple smoke.", ch, NULL, NULL, TO_ROOM);
send_to_char ("You conjure a cloud of purple smoke.\n\r", ch);
for (ich = ch->in_room->people; ich != NULL; ich = ich->next_in_room)
{
if (IS_IMMORTAL (ich))
continue;
if (!IS_NPC (ich) && IS_SET (ich->act, PLR_WIZINVIS) && ch->level < 2)
continue;
if (ich == ch || saves_spell (level, ich))
continue;
affect_strip (ich, gsn_invis);
affect_strip (ich, gsn_mass_invis);
affect_strip (ich, gsn_sneak);
REMOVE_BIT (ich->affected_by, AFF_HIDE);
REMOVE_BIT (ich->affected_by, AFF_INVISIBLE);
REMOVE_BIT (ich->affected_by, AFF_SNEAK);
if (ch->level >= 2 && ich->level != LEVEL_IMMORTAL)
{
REMOVE_BIT (ich->act, PLR_WIZINVIS);
}
if (number_range (1, 3) == 2)
{
if (IS_SET (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS))
{
if (ch->fighting == NULL)
{
if (IS_SET (ich->newbits, NEW_DARKNESS))
{
act ("The darkness surrounding $N fades.", ch, NULL, ich,
TO_CHAR);
stc ("The darkness surrounding you fades!\n\r", ich);
act ("The darkness surrounding $N fades.", ch, NULL, ich,
TO_NOTVICT);
REMOVE_BIT (ich->newbits, NEW_DARKNESS);
REMOVE_BIT (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
}
}
}
}
act ("$n is revealed!", ich, NULL, NULL, TO_ROOM);
send_to_char ("You are revealed!\n\r", ich);
}
if (IS_SET (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS)
&& number_range (1, 100) < 20)
{
act ("$n banishes the darkness from the room.", ch, NULL, NULL,
TO_ROOM);
act ("You banish the darkness from the room.", ch, NULL, NULL, TO_CHAR);
REMOVE_BIT (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
}
return;
}
void spell_fly (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_FLYING))
return;
af.type = sn;
af.duration = level + 3;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_FLYING;
affect_to_char (victim, &af);
send_to_char ("You rise up off the ground.\n\r", victim);
act ("$n rises up off the ground.", victim, NULL, NULL, TO_ROOM);
return;
}
void spell_gate (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim;
victim = create_mobile (get_mob_index (MOB_VNUM_VAMPIRE));
SET_BIT (victim->act, ACT_NOEXP);
act ("$N fades into existance.", ch, NULL, victim, TO_CHAR);
act ("$N fades into existance.", ch, NULL, victim, TO_ROOM);
char_to_room (victim, ch->in_room);
return;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
void spell_general_purpose (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = number_range (25, 100);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
return;
}
void spell_giant_strength (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 1 + (level >= 18) + (level >= 25);
af.bitvector = 0;
affect_to_char (victim, &af);
send_to_char ("You feel stronger.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_harm (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = UMAX (20, victim->hit - dice (1, 4));
if (saves_spell (level, victim))
dam = UMIN (50, dam / 4);
dam = UMIN (100, dam);
damage (ch, victim, dam, sn);
return;
}
void spell_heal (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (ch != victim && IS_NEWBIE(ch)) return;
int heal = number_range (4 * level, 8 * level);
int dheal;
if (!IS_NPC(ch))
{
if ((get_hours (victim) > 10) && (get_hours (ch) < 10))
{
send_to_char ("You cannot do that.\n\r", ch);
return;
}
/* if (victim->fight_timer > 0 && ch->fight_timer < 1)
{
stc("You cannot do that\n\r");
return;
}
*/
if (!IS_NPC (ch) && ch->level < 3 && !IS_NPC (victim) && victim->level >= 3)
{
stc ("You must be an avatar to heal an avatar!\n\r", ch);
return;
}
if (ch->pcdata->pkill_timer > 0 && ch != victim)
{
stc("You cannot do that with a pk timer\n\r", ch);
return;
}
}
if (IS_SET (ch->extra2, AURA_NO_MAGIC))
do_auranomagic (ch, "");
if (victim->hit < victim->max_hit)
{
if ((IS_CLASS (ch, CLASS_DROW)) && (IS_SET (ch->special, SPC_DROW_CLE)))
{
dheal = number_range (8 * level, 16 * level);
victim->hit = UMIN (victim->hit + dheal, victim->max_hit);
}
victim->hit = UMIN (victim->hit + heal, victim->max_hit);
}
update_pos (victim);
send_to_char ("A warm feeling fills your body.\n\r", victim);
if (ch == victim)
act ("$n heals $mself.", ch, NULL, NULL, TO_ROOM);
else
act ("$n heals $N.", ch, NULL, victim, TO_NOTVICT);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
if (IS_CLASS (ch, CLASS_MAGE) && victim->position == POS_FIGHTING)
WAIT_STATE (ch, 36);
return;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
void spell_high_explosive (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = number_range (30, 120);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
return;
}
void spell_identify (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
char buf[MAX_STRING_LENGTH];
char type[MSL];
AFFECT_DATA *paf;
int itemtype;
act ("You examine $p carefully.", ch, obj, NULL, TO_CHAR);
act ("$n examines $p carefully.", ch, obj, NULL, TO_ROOM);
sprintf (buf,
"Object '%s' is type %s, extra flags %s.\n\rWeight is %d, value is %d.\n\r",
obj->name, item_type_name (obj->item_type),
extra_bit_name (obj->extra_flags), obj->weight, obj->cost);
send_to_char (buf, ch);
if (IS_SET (obj->spectype, SITEM_TRANSPORTER)
|| IS_SET (obj->spectype, SITEM_TELEPORTER))
{
if (get_room_index (obj->specpower) != NULL)
{
sprintf (buf, "This object transports you to %s.\n\r",
(get_room_index (obj->specpower))->name);
stc (buf, ch);
}
else
stc ("This object transports you to a room that doesnt exist\n\r",
ch);
}
if (obj->points > 0 && obj->item_type != ITEM_QUEST
&& obj->item_type != ITEM_PAGE && obj->item_type != ITEM_ETOKEN)
{
sprintf (buf, "Quest point value is %d.\n\r", obj->points);
send_to_char (buf, ch);
}
if (obj->questmaker != NULL && strlen (obj->questmaker) > 1
&& obj->questowner != NULL && strlen (obj->questowner) > 1)
{
sprintf (buf, "This object was created by %s, and is owned by %s.\n\r",
obj->questmaker, obj->questowner);
send_to_char (buf, ch);
}
else if (obj->questmaker != NULL && strlen (obj->questmaker) > 1)
{
sprintf (buf, "This object was created by %s.\n\r", obj->questmaker);
send_to_char (buf, ch);
}
else if (obj->questowner != NULL && strlen (obj->questowner) > 1)
{
sprintf (buf, "This object is owned by %s.\n\r", obj->questowner);
send_to_char (buf, ch);
}
if (IS_SET (obj->quest2, QUEST2_INDEST))
send_to_char ("This item is indestructible.\n\r", ch);
if (IS_SET (obj->quest2, QUEST2_OWNERSHIP))
send_to_char ("This item has had its ownership set.\n\r", ch);
if (IS_SET (obj->quest, QUEST_ENCHANTED))
send_to_char ("This item has been enchanted.\n\r", ch);
if (IS_SET (obj->quest, QUEST_SPELLPROOF))
send_to_char ("This item is resistant to offensive spells.\n\r", ch);
if (IS_SET (obj->spectype, SITEM_DEMONIC))
send_to_char ("This item is crafted from demonsteel.\n\r", ch);
else if (IS_SET (obj->spectype, SITEM_SILVER))
send_to_char ("This item is crafted from gleaming silver.\n\r", ch);
switch (obj->item_type)
{
case ITEM_PILL:
case ITEM_SCROLL:
case ITEM_NEWTOKEN:
switch (obj->value[0])
{
default:
sprintf(type,"None");
break;
case 0:
sprintf(type,"None");
break;
case 1:
sprintf(type,"Hitroll");
break;
case 2:
sprintf(type,"Damroll");
break;
case 3:
sprintf(type,"AC");
break;
case 4:
sprintf(type,"-HP");
break;
case 5:
sprintf(type,"-Mana");
break;
case 6:
sprintf(type,"-Move");
break;
case 7:
sprintf(type,"Wear Location");
break;
case 8:
sprintf(type,"Rename");
break;
case 9:
sprintf(type,"High Judge Token\n\r");
break;
case 10:
sprintf(type,"Implementor Token\n\r");
break;
case 11:
sprintf(type,"Owner Token\n\r");
break;
}
sprintf(buf, "Enhancement: %s\n\rAmount: %d\n\r", type, obj->value[1]);
send_to_char(buf, ch);
break;
case ITEM_POTION:
sprintf (buf, "Level %d spells of:", obj->value[0]);
send_to_char (buf, ch);
if (obj->value[1] >= 0 && obj->value[1] < MAX_SKILL)
{
send_to_char (" '", ch);
send_to_char (skill_table[obj->value[1]].name, ch);
send_to_char ("'", ch);
}
if (obj->value[2] >= 0 && obj->value[2] < MAX_SKILL)
{
send_to_char (" '", ch);
send_to_char (skill_table[obj->value[2]].name, ch);
send_to_char ("'", ch);
}
if (obj->value[3] >= 0 && obj->value[3] < MAX_SKILL)
{
send_to_char (" '", ch);
send_to_char (skill_table[obj->value[3]].name, ch);
send_to_char ("'", ch);
}
send_to_char (".\n\r", ch);
break;
case ITEM_ETOKEN:
sprintf (buf, "ENERGY point value is %d.\n\r", obj->value[0]);
send_to_char (buf, ch);
break;
case ITEM_QUEST:
sprintf (buf, "Quest point value is %d.\n\r", obj->value[0]);
send_to_char (buf, ch);
break;
case ITEM_QUESTCARD:
sprintf (buf, "Quest completion reward is %d quest points.\n\r",
obj->level);
send_to_char (buf, ch);
break;
case ITEM_WAND:
case ITEM_STAFF:
sprintf (buf, "Has %d(%d) charges of level %d", obj->value[1],
obj->value[2], obj->value[0]);
send_to_char (buf, ch);
if (obj->value[3] >= 0 && obj->value[3] < MAX_SKILL)
{
send_to_char (" '", ch);
send_to_char (skill_table[obj->value[3]].name, ch);
send_to_char ("'", ch);
}
send_to_char (".\n\r", ch);
break;
case ITEM_WEAPON:
if (obj->value[3] == 1)
sprintf (buf, "%s is a slicing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 2)
sprintf (buf, "%s is a stabbing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 3)
sprintf (buf, "%s is a slashing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 4)
sprintf (buf, "%s is a whipping weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 5)
sprintf (buf, "%s is a clawing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 6)
sprintf (buf, "%s is a blasting weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 7)
sprintf (buf, "%s is a pounding weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 8)
sprintf (buf, "%s is a crushing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 9)
sprintf (buf, "%s is a grepping weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 10)
sprintf (buf, "%s is a biting weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 11)
sprintf (buf, "%s is a piercing weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 12)
sprintf (buf, "%s is a sucking weapon\n\r",
capitalize (obj->short_descr));
else if (obj->value[3] == 0)
sprintf (buf, "%s is an unarmed weapon\n\r",
capitalize (obj->short_descr));
stc (buf, ch);
sprintf (buf, "Damage is %d to %d (average %d).\n\r", obj->value[1],
obj->value[2], (obj->value[1] + obj->value[2]) / 2);
send_to_char (buf, ch);
switch (obj->pIndexData->vnum) // Add new artifact idents here
{
case ARTI_SHATTERED_BLADE:
{
stcprintf (ch, "%s has been shattered and is continously regenerating the slivers that break off in combat.\n\r", capitalize(obj->short_descr));
break;
}
}
if (obj->value[0] >= 1000)
itemtype = obj->value[0] - ((obj->value[0] / 1000) * 1000);
else
itemtype = obj->value[0];
if (itemtype > 0)
{
if (obj->level < 10)
sprintf (buf, "%s is a minor spell weapon.\n\r",
capitalize (obj->short_descr));
else if (obj->level < 20)
sprintf (buf, "%s is a lesser spell weapon.\n\r",
capitalize (obj->short_descr));
else if (obj->level < 30)
sprintf (buf, "%s is an average spell weapon.\n\r",
capitalize (obj->short_descr));
else if (obj->level < 40)
sprintf (buf, "%s is a greater spell weapon.\n\r",
capitalize (obj->short_descr));
else if (obj->level < 50)
sprintf (buf, "%s is a major spell weapon.\n\r",
capitalize (obj->short_descr));
else if (obj->level > 50)
sprintf (buf, "%s is an ultimate spell weapon.\n\r",
capitalize (obj->short_descr));
else
sprintf (buf, "%s is a supreme spell weapon.\n\r",
capitalize (obj->short_descr));
send_to_char (buf, ch);
}
if (itemtype == 1)
sprintf (buf, "This weapon is dripping with corrosive acid.\n\r");
else if (itemtype == 4)
sprintf (buf, "This weapon radiates an aura of darkness.\n\r");
else if (itemtype == 30)
sprintf (buf, "This ancient relic is the bane of all evil.\n\r");
else if (itemtype == 34)
sprintf (buf,
"This vampiric weapon drinks the souls of its victims.\n\r");
else if (itemtype == 37)
sprintf (buf, "This weapon has been tempered in hellfire.\n\r");
else if (itemtype == 48)
sprintf (buf, "This weapon crackles with sparks of lightning.\n\r");
else if (itemtype == 53)
sprintf (buf, "This weapon is dripping with a dark poison.\n\r");
else if (itemtype > 0)
sprintf (buf,
"This weapon has been imbued with the power of %s.\n\r",
skill_table[itemtype].name);
if (itemtype > 0)
send_to_char (buf, ch);
if (obj->value[0] >= 1000)
itemtype = obj->value[0] / 1000;
else
break;
if (itemtype == 4)
sprintf (buf, "This weapon radiates an aura of darkness.\n\r");
else if (itemtype == 60)
sprintf (buf,
"This weapon allows the wielder to see hidden things.\n\r");
else if (itemtype == 27 || itemtype == 2)
sprintf (buf,
"This weapon allows the wielder to see invisible things.\n\r");
else if (itemtype == 39 || itemtype == 3)
sprintf (buf, "This weapon grants the power of flight.\n\r");
else if (itemtype == 45 || itemtype == 1)
sprintf (buf,
"This weapon allows the wielder to see in the dark.\n\r");
else if (itemtype == 46 || itemtype == 5)
sprintf (buf,
"This weapon renders the wielder invisible to the human eye.\n\r");
else if (itemtype == 52 || itemtype == 6)
sprintf (buf,
"This weapon allows the wielder to walk through solid doors.\n\r");
else if (itemtype == 54 || itemtype == 7)
sprintf (buf,
"This holy weapon protects the wielder from evil.\n\r");
else if (itemtype == 57 || itemtype == 8)
sprintf (buf,
"This ancient weapon protects the wielder in combat.\n\r");
else if (itemtype == 9)
sprintf (buf,
"This crafty weapon allows the wielder to walk in complete silence.\n\r");
else if (itemtype == 10)
sprintf (buf,
"This powerful weapon surrounds its wielder with a shield of lightning.\n\r");
else if (itemtype == 11)
sprintf (buf,
"This powerful weapon surrounds its wielder with a shield of fire.\n\r");
else if (itemtype == 12)
sprintf (buf,
"This powerful weapon surrounds its wielder with a shield of ice.\n\r");
else if (itemtype == 13)
sprintf (buf,
"This powerful weapon surrounds its wielder with a shield of acid.\n\r");
else if (itemtype == 14)
sprintf (buf,
"This weapon protects its wielder from clan DarkBlade guardians.\n\r");
else if (itemtype == 15)
sprintf (buf,
"This ancient weapon surrounds its wielder with a shield of chaos.\n\r");
else if (itemtype == 16)
sprintf (buf,
"This ancient weapon regenerates the wounds of its wielder.\n\r");
else if (itemtype == 17)
sprintf (buf,
"This ancient weapon allows its wielder to move at supernatural speed.\n\r");
else if (itemtype == 18)
sprintf (buf,
"This razor sharp weapon can slice through armour without difficulty.\n\r");
else if (itemtype == 19)
sprintf (buf,
"This ancient weapon protects its wearer from player attacks.\n\r");
else if (itemtype == 20)
sprintf (buf,
"This ancient weapon surrounds its wielder with a shield of darkness.\n\r");
else if (itemtype == 21)
sprintf (buf,
"This ancient weapon grants superior protection to its wielder.\n\r");
else if (itemtype == 22)
sprintf (buf,
"This ancient weapon grants its wielder supernatural vision.\n\r");
else if (itemtype == 23)
sprintf (buf,
"This ancient weapon makes its wielder fleet-footed.\n\r");
else if (itemtype == 24)
sprintf (buf,
"This ancient weapon conceals its wielder from sight.\n\r");
else if (itemtype == 25)
sprintf (buf,
"This ancient weapon invokes the power of the beast.\n\r");
else if (itemtype == 26)
sprintf (buf,
"This ancient weapon invokes the overwhelming power of the sun.\n\r");
else if (itemtype == 28)
sprintf (buf,
"This ancient weapon invokes the surging energy of the storm.\n\r");
else
sprintf (buf, "This item is bugged...please report it.\n\r");
if (itemtype > 0)
send_to_char (buf, ch);
if IS_WEAP
(obj, WEAPON_POISON)
stc ("This Weapon is dripping with poison.\n\r", ch);
if IS_WEAP
(obj, WEAPON_FLAMING)
stc ("This Weapon is engulfed in flames.\n\r", ch);
if IS_WEAP
(obj, WEAPON_FROST) stc ("This Weapon is encased in ice.\n\r", ch);
if IS_SET
(obj->quest, QUEST_MALLEABLE)
stc ("This weapon has had its spirit manipulated.\n\r", ch);
break;
case ITEM_DRAGONGEM:
sprintf (buf, "This item is a dragon gem.\n\r");
stc (buf, ch);
break;
case ITEM_PIECE:
if (obj->value[2] == 1)
send_to_char ("This is one piece of the item.\n\r", ch);
else
sprintf (buf, "This contains %d pieces of the item.\n\r",
obj->value[2]);
if (obj->value[2] > 0)
send_to_char (buf, ch);
else
send_to_char ("This item is bugged. (How unusual :)\n\r", ch);
break;
case ITEM_ARMOR:
sprintf (buf, "Armor class is %d.\n\r", obj->value[0]);
send_to_char (buf, ch);
if (obj->value[3] < 1)
break;
if (obj->value[3] == 4)
sprintf (buf, "This object radiates an aura of darkness.\n\r");
else if (obj->value[3] == 27 || obj->value[3] == 2)
sprintf (buf,
"This item allows the wearer to see invisible things.\n\r");
else if (obj->value[3] == 60)
sprintf (buf,
"This item allows the wearer to see hidden things.\n\r");
else if (obj->value[3] == 39 || obj->value[3] == 3)
sprintf (buf, "This object grants the power of flight.\n\r");
else if (obj->value[3] == 45 || obj->value[3] == 1)
sprintf (buf, "This item allows the wearer to see in the dark.\n\r");
else if (obj->value[3] == 46 || obj->value[3] == 5)
sprintf (buf,
"This object renders the wearer invisible to the human eye.\n\r");
else if (obj->value[3] == 52 || obj->value[3] == 6)
sprintf (buf,
"This object allows the wearer to walk through solid doors.\n\r");
else if (obj->value[3] == 54 || obj->value[3] == 7)
sprintf (buf, "This holy relic protects the wearer from evil.\n\r");
else if (obj->value[3] == 57 || obj->value[3] == 8)
sprintf (buf,
"This ancient relic protects the wearer in combat.\n\r");
else if (obj->value[3] == 9)
sprintf (buf,
"This crafty item allows the wearer to walk in complete silence.\n\r");
else if (obj->value[3] == 10)
sprintf (buf,
"This powerful item surrounds its wearer with a shield of lightning.\n\r");
else if (obj->value[3] == 11)
sprintf (buf,
"This powerful item surrounds its wearer with a shield of fire.\n\r");
else if (obj->value[3] == 12)
sprintf (buf,
"This powerful item surrounds its wearer with a shield of ice.\n\r");
else if (obj->value[3] == 13)
sprintf (buf,
"This powerful item surrounds its wearer with a shield of acid.\n\r");
else if (obj->value[3] == 14)
sprintf (buf,
"This object protects its wearer from clan DarkBlade guardians.\n\r");
else if (obj->value[3] == 15)
sprintf (buf,
"This ancient item surrounds its wearer with a shield of chaos.\n\r");
else if (obj->value[3] == 16)
sprintf (buf,
"This ancient item regenerates the wounds of its wearer.\n\r");
else if (obj->value[3] == 17)
sprintf (buf,
"This ancient item allows its wearer to move at supernatural speed.\n\r");
else if (obj->value[3] == 18)
sprintf (buf,
"This powerful item allows its wearer to shear through armour without difficulty.\n\r");
else if (obj->value[3] == 19)
sprintf (buf,
"This powerful item protects its wearer from player attacks.\n\r");
else if (obj->value[3] == 20)
sprintf (buf,
"This ancient item surrounds its wearer with a shield of darkness.\n\r");
else if (obj->value[3] == 21)
sprintf (buf,
"This ancient item grants superior protection to its wearer.\n\r");
else if (obj->value[3] == 22)
sprintf (buf,
"This ancient item grants its wearer supernatural vision.\n\r");
else if (obj->value[3] == 23)
sprintf (buf,
"This ancient item makes its wearer fleet-footed.\n\r");
else if (obj->value[3] == 24)
sprintf (buf,
"This ancient item conceals its wearer from sight.\n\r");
else if (obj->value[3] == 25)
sprintf (buf,
"This ancient item invokes the power of the beast.\n\r");
else if (obj->value[3] == 26)
sprintf (buf,
"This ancient item invokes the overwhelming power of the sun.\n\r");
else if (obj->value[3] == 28)
sprintf (buf,
"This ancient item invokes the surging energy of the storm.\n\r");
else
sprintf (buf, "This item is bugged...please report it.\n\r");
if (obj->value[3] > 0)
send_to_char (buf, ch);
break;
}
for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next)
{
if (paf->location != APPLY_NONE && paf->modifier != 0)
{
sprintf (buf, "Affects %s by %d.\n\r",
affect_loc_name (paf->location), paf->modifier);
send_to_char (buf, ch);
}
}
for (paf = obj->affected; paf != NULL; paf = paf->next)
{
if (paf->location != APPLY_NONE && paf->modifier != 0)
{
sprintf (buf, "Affects %s by %d.\n\r",
affect_loc_name (paf->location), paf->modifier);
send_to_char (buf, ch);
}
}
return;
}
void spell_infravision (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_INFRARED))
return;
act ("$n's eyes glow red.\n\r", ch, NULL, NULL, TO_ROOM);
af.type = sn;
af.duration = 2 * level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INFRARED;
affect_to_char (victim, &af);
send_to_char ("Your eyes glow red.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_invis (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_INVISIBLE))
return;
act ("$n fades out of existence.", victim, NULL, NULL, TO_ROOM);
af.type = sn;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INVISIBLE;
affect_to_char (victim, &af);
send_to_char ("You fade out of existence.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_know_alignment (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char *msg;
int ap;
ap = victim->alignment;
if (ap > 700)
msg = "$N has an aura as white as the driven snow.";
else if (ap > 350)
msg = "$N is of excellent moral character.";
else if (ap > 100)
msg = "$N is often kind and thoughtful.";
else if (ap > -100)
msg = "$N doesn't have a firm moral commitment.";
else if (ap > -350)
msg = "$N lies to $S friends.";
else if (ap > -700)
msg = "$N's slash DISEMBOWELS you!";
else
msg = "I'd rather just not say anything at all about $N.";
act (msg, ch, NULL, victim, TO_CHAR);
return;
}
void spell_lightning_bolt (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
10,
15, 15, 15, 20, 20, 25, 25, 25, 25, 28,
31, 34, 37, 40, 40, 41, 42, 42, 43, 44,
44, 45, 46, 46, 47, 48, 48, 49, 50, 50,
51, 52, 52, 53, 54, 54, 55, 56, 56, 57,
58, 58, 59, 60, 60, 61, 62, 62, 63, 64,
70, 80, 90, 120, 150, 200, 250, 300, 350, 400
};
int dam;
int hp;
if (IS_ITEMAFF (victim, ITEMA_SHOCKSHIELD))
return;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_LIGHTNING))
victim->hit = hp;
return;
}
void spell_locate_object (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *obj;
OBJ_DATA *in_obj;
bool found;
int count = 0;
char buf2[10];
found = FALSE;
for (obj = object_list; obj != NULL; obj = obj->next)
{
if (!can_see_obj (ch, obj) || !is_name (target_name, obj->name))
continue;
found = TRUE;
if (IS_SET (obj->quest, ITEM_EQUEST) || (obj->item_type == ITEM_STOKEN) || (obj->item_type == ITEM_NEWTOKEN))
{
continue;
}
if (obj->item_type == ITEM_WGATE)
{
continue;
}
for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj)
;
if (obj->carried_by != NULL && !can_see (ch, obj->carried_by))
{
found = FALSE;
continue;
}
if ((obj->carried_by != NULL) && (IS_IMMORTAL (obj->carried_by)))
{
found = FALSE;
continue;
}
if (in_obj->carried_by != NULL)
{
sprintf (buf, "%s#n carried by %s.\n\r", obj->short_descr,
PERS (in_obj->carried_by, ch));
}
else
{
sprintf (buf, "%s#n in %s.\n\r", obj->short_descr,
in_obj->in_room ==
NULL ? "somewhere" : in_obj->in_room->name);
}
buf[0] = UPPER (buf[0]);
sprintf (buf2, "[%3d] ", count + 1);
stc (buf2, ch);
send_to_char (buf, ch);
if (count > 75) // && (ch->spl[PURPLE_MAGIC] < 240))
break;
else
count++;
}
if (!found)
send_to_char ("Nothing like that in hell, earth, or heaven.\n\r", ch);
return;
}
void spell_magic_missile (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const sh_int dam_each[] = {
0,
3, 3, 4, 4, 5, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 14, 14, 14, 14, 14,
15, 20, 25, 30, 35, 40, 45, 55, 65, 75
};
int dam;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
damage (ch, victim, dam, sn);
return;
}
void spell_mass_invis (int sn, int level, CHAR_DATA * ch, void *vo)
{
AFFECT_DATA af;
CHAR_DATA *gch;
for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room)
{
if (!is_same_group (gch, ch) || IS_AFFECTED (gch, AFF_INVISIBLE))
continue;
act ("$n slowly fades out of existence.", gch, NULL, NULL, TO_ROOM);
send_to_char ("You slowly fade out of existence.\n\r", gch);
af.type = sn;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INVISIBLE;
affect_to_char (gch, &af);
}
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_null (int sn, int level, CHAR_DATA * ch, void *vo)
{
send_to_char ("That's not a spell!\n\r", ch);
return;
}
void spell_pass_door (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_PASS_DOOR))
return;
af.type = sn;
af.duration = number_fuzzy (level / 4);
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PASS_DOOR;
affect_to_char (victim, &af);
act ("$n turns translucent.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You turn translucent.\n\r", victim);
return;
}
void spell_poison (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_INPUT_LENGTH];
/* Ghosts cannot be poisoned - KaVir */
if (IS_NPC (victim) && IS_AFFECTED (victim, AFF_ETHEREAL))
return;
return;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE)
&& IS_VAMPAFF (victim, VAM_SERPENTIS))
return;
else if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_WEREWOLF)
&& victim->pcdata->powers[WPOWER_SPIDER] > 2)
return;
else if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_DROW)
&& IS_SET (victim->pcdata->powers[1], DPOWER_DROWPOISON))
return;
else if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_NINJA)
&& victim->pcdata->powers[NPOWER_NINGENNO] > 4)
return;
if (saves_spell (level, victim))
return;
af.type = sn;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 0 - number_range (1, 3);
af.bitvector = AFF_POISON;
affect_join (victim, &af);
send_to_char ("You feel very sick.\n\r", victim);
if (ch == victim)
return;
if (!IS_NPC (victim))
sprintf (buf, "%s looks very sick as your poison takes affect.\n\r",
victim->name);
else
sprintf (buf, "%s looks very sick as your poison takes affect.\n\r",
victim->short_descr);
send_to_char (buf, ch);
return;
}
void spell_protection (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_PROTECT))
return;
af.type = sn;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PROTECT;
affect_to_char (victim, &af);
send_to_char ("You feel protected.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
void spell_refresh (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
victim->move = UMIN (victim->move + level, victim->max_move);
act ("$n looks less tired.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You feel less tired.\n\r", victim);
if (!IS_NPC (victim) && victim->sex == SEX_MALE
&& victim->pcdata->stage[0] < 1 && victim->pcdata->stage[2] > 0)
victim->pcdata->stage[2] = 0;
return;
}
void spell_remove_curse (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim;
OBJ_DATA *obj;
char arg[MAX_INPUT_LENGTH];
one_argument (target_name, arg);
if (arg[0] == '\0')
{
send_to_char ("Remove curse on what?\n\r", ch);
return;
}
if ((victim = get_char_world (ch, target_name)) != NULL)
{
if (is_affected (victim, gsn_curse))
{
affect_strip (victim, gsn_curse);
send_to_char ("You feel better.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
}
return;
}
if ((obj = get_obj_carry (ch, arg)) != NULL)
{
if (IS_SET (obj->extra_flags, ITEM_NOREMOVE))
{
REMOVE_BIT (obj->extra_flags, ITEM_NOREMOVE);
act ("$p flickers with energy.", ch, obj, NULL, TO_CHAR);
}
else if (IS_SET (obj->extra_flags, ITEM_NODROP))
{
REMOVE_BIT (obj->extra_flags, ITEM_NODROP);
act ("$p flickers with energy.", ch, obj, NULL, TO_CHAR);
}
return;
}
send_to_char ("No such creature or object to remove curse on.\n\r", ch);
return;
}
void spell_sanctuary (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_SANCTUARY))
return;
af.type = sn;
af.duration = number_fuzzy (level / 8);
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SANCTUARY;
affect_to_char (victim, &af);
act ("$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You are surrounded by a white aura.\n\r", victim);
return;
}
/*
void spell_holyaura( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED(victim, AFF_HOLYAURA) )
return;
af.type = sn;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_HOLYAURA;
affect_to_char( victim, &af );
act( "$n is surrounded by a holy aura.", victim, NULL, NULL, TO_ROOM );
send_to_char( "You are surrounded by a holy aura.\n\r", victim );
return;
}
*/
void spell_shield (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 8 + level;
af.location = APPLY_AC;
af.modifier = -20;
af.bitvector = 0;
affect_to_char (victim, &af);
act ("$n is surrounded by a force shield.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You are surrounded by a force shield.\n\r", victim);
return;
}
void spell_shocking_grasp (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each[] = {
10,
10, 10, 15, 15, 15, 20, 20, 25, 29, 33,
36, 39, 39, 39, 40, 40, 41, 41, 42, 42,
43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
48, 48, 49, 49, 50, 50, 51, 51, 52, 52,
53, 53, 54, 54, 55, 55, 56, 56, 57, 57,
60, 70, 85, 100, 125, 150, 175, 200, 225, 300
};
int dam;
level = UMIN (level, sizeof (dam_each) / sizeof (dam_each[0]) - 1);
level = UMAX (0, level);
dam = number_range (dam_each[level] / 2, dam_each[level] * 2);
if (saves_spell (level, victim))
dam /= 2;
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_LIGHTNING))
dam /= 1.5;
damage (ch, victim, dam, sn);
return;
}
void spell_sleep (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_SLEEP)
|| level < victim->level || (!IS_NPC (victim)
&& IS_IMMUNE (victim, IMM_SLEEP))
|| (IS_NPC (victim) && IS_AFFECTED (victim, AFF_ETHEREAL))
|| saves_spell (level, victim))
return;
af.type = sn;
af.duration = 4 + level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SLEEP;
affect_join (victim, &af);
if (IS_AWAKE (victim))
{
send_to_char ("You feel very sleepy ..... zzzzzz.\n\r", victim);
act ("$n goes to sleep.", victim, NULL, NULL, TO_ROOM);
victim->position = POS_SLEEPING;
}
return;
}
void spell_stone_skin (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (ch, sn))
return;
af.type = sn;
af.duration = level;
af.location = APPLY_AC;
af.modifier = -40;
af.bitvector = 0;
affect_to_char (victim, &af);
act ("$n's skin turns to stone.", victim, NULL, NULL, TO_ROOM);
send_to_char ("Your skin turns to stone.\n\r", victim);
return;
}
void spell_summon (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim;
CHAR_DATA *mount;
if ((victim = get_char_world (ch, target_name)) == NULL
|| victim == ch
|| victim->in_room == NULL
|| IS_SET (victim->in_room->room_flags, ROOM_SAFE)
|| IS_SET (victim->in_room->room_flags, ROOM_PRIVATE)
|| IS_SET (victim->in_room->room_flags, ROOM_SOLITARY)
|| IS_SET (victim->in_room->room_flags, ROOM_NO_RECALL)
|| victim->level >= level + 3
|| victim->fighting != NULL
|| victim->in_room->area != ch->in_room->area
|| (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
|| (IS_NPC (victim) && IS_AFFECTED (victim, AFF_ETHEREAL))
|| (IS_NPC (victim) && saves_spell (level, victim)))
{
send_to_char ("You failed.\n\r", ch);
return;
}
act ("$n disappears suddenly.", victim, NULL, NULL, TO_ROOM);
char_from_room (victim);
char_to_room (victim, ch->in_room);
act ("$n arrives suddenly.", victim, NULL, NULL, TO_ROOM);
act ("$N has summoned you!", victim, NULL, ch, TO_CHAR);
do_look (victim, "auto");
if ((mount = victim->mount) == NULL)
return;
char_from_room (mount);
char_to_room (mount, get_room_index (victim->in_room->vnum));
do_look (mount, "auto");
return;
}
void spell_teleport (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *mount;
ROOM_INDEX_DATA *pRoomIndex;
int to_room;
if (victim->in_room == NULL
|| IS_SET (victim->in_room->room_flags, ROOM_NO_RECALL)
|| IS_SET (victim->in_room->room_flags, ROOM_SAFE)
|| IS_SET (victim->in_room->room_flags, ROOM_NO_TELEPORT)
|| IS_SET (victim->in_room->room_flags, ROOM_GOD)
|| (!IS_NPC (ch) && victim->fighting != NULL) || (!IS_NPC (victim)
&&
!IS_IMMUNE (victim,
IMM_SUMMON))
|| (victim != ch
&& (saves_spell (level, victim) || saves_spell (level, victim))))
{
send_to_char ("You failed.\n\r", ch);
return;
}
if (is_inarena (victim))
return;
for (;;)
{
to_room = number_range (0, top_vnum_room);
pRoomIndex = get_room_index (to_room);
if (pRoomIndex != NULL)
if (!IS_SET (pRoomIndex->room_flags, ROOM_PRIVATE)
&& !IS_SET (pRoomIndex->room_flags, ROOM_SOLITARY)
&& !IS_SET (pRoomIndex->room_flags, ROOM_NO_TELEPORT)
&& !IS_SET (pRoomIndex->room_flags, ROOM_GOD)
&& !IS_SET (pRoomIndex->room_flags, ROOM_CCHAMBER)
&& !IS_SET (pRoomIndex->area->aflags, AFLAG_HQ)
&& to_room != 30008 && to_room != 30002)
break;
}
act ("$n slowly fades out of existence.", victim, NULL, NULL, TO_ROOM);
char_from_room (victim);
char_to_room (victim, pRoomIndex);
act ("$n slowly fades into existence.", victim, NULL, NULL, TO_ROOM);
do_look (victim, "auto");
if ((mount = ch->mount) == NULL)
return;
char_from_room (mount);
char_to_room (mount, ch->in_room);
do_look (mount, "auto");
send_teleport (victim);
if (IS_CLASS(ch, CLASS_MAGE))
WAIT_STATE (ch, skill_table[sn].beats);
return;
}
void spell_ventriloquate (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf1[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
char speaker[MAX_INPUT_LENGTH];
CHAR_DATA *vch;
target_name = one_argument (target_name, speaker);
sprintf (buf1, "%s says '%s'.\n\r", speaker, target_name);
sprintf (buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name);
buf1[0] = UPPER (buf1[0]);
for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
{
if (!is_name (speaker, vch->name))
send_to_char (saves_spell (level, vch) ? buf2 : buf1, vch);
}
return;
}
void spell_weaken (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn) || saves_spell (level, victim))
return;
af.type = sn;
af.duration = level / 2;
af.location = APPLY_STR;
af.modifier = -2;
af.bitvector = 0;
affect_to_char (victim, &af);
send_to_char ("You feel weaker.\n\r", victim);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
return;
}
/*
* This is for muds that _want_ scrolls of recall.
* Ick.
*/
void spell_word_of_recall (int sn, int level, CHAR_DATA * ch, void *vo)
{
do_recall ((CHAR_DATA *) vo, "");
return;
}
/*
* NPC spells.
*/
void spell_acid_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
int dam;
int hpch;
int hp;
if (IS_ITEMAFF (victim, ITEMA_ACIDSHIELD) && number_range(1,2) == 1)
return;
if (number_percent () < 2 * level && !saves_spell (level, victim))
{
for (obj_lose = ch->carrying; obj_lose != NULL; obj_lose = obj_next)
{
int iWear;
obj_next = obj_lose->next_content;
if (number_bits (2) != 0)
continue;
if (IS_SET (obj_lose->quest, QUEST_SPELLPROOF))
continue;
if (IS_SET (obj_lose->quest2, QUEST2_INDEST))
continue;
switch (obj_lose->item_type)
{
case ITEM_ARMOR:
if (obj_lose->value[0] > 0)
{
act ("$p is pitted and etched!", victim, obj_lose, NULL,
TO_CHAR);
if ((iWear = obj_lose->wear_loc) != WEAR_NONE)
victim->armor -= apply_ac (obj_lose, iWear);
obj_lose->value[0] -= 1;
obj_lose->cost = 0;
if (iWear != WEAR_NONE)
victim->armor += apply_ac (obj_lose, iWear);
}
break;
case ITEM_CONTAINER:
if (obj_lose->contains)
{
remove_owned (obj_lose, ch);
remove_unowned (obj_lose, ch);
}
act ("$p fumes and dissolves!", victim, obj_lose, NULL, TO_CHAR);
sprintf (log_buf, "%s's %s is consumed by Acid Breath",
victim->name, obj_lose->short_descr);
log_string (log_buf, NULL);
extract_obj (obj_lose);
break;
}
}
}
hpch = UMAX (10, ch->hit);
dam = number_range (hpch / 16 + 1, hpch / 8);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_ACID))
victim->hit = hp;
return;
}
void spell_fire_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
int dam;
int hpch;
int hp;
if (IS_ITEMAFF (victim, ITEMA_FIRESHIELD) && number_range(1,2) == 1)
return;
if (WORN_ARTIFACT (victim, ARTI_DEMONS_HEART))
return;
if (number_percent () < 2 * level && !saves_spell (level, victim))
{
for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
{
char *msg;
obj_next = obj_lose->next_content;
if (number_bits (2) != 0)
continue;
if (IS_SET (obj_lose->quest, QUEST_SPELLPROOF))
continue;
if (IS_SET (obj_lose->quest2, QUEST2_INDEST))
continue;
switch (obj_lose->item_type)
{
default:
continue;
case ITEM_CONTAINER:
msg = "$p ignites and burns!";
break;
case ITEM_POTION:
msg = "$p bubbles and boils!";
break;
case ITEM_SCROLL:
msg = "$p crackles and burns!";
break;
case ITEM_STAFF:
msg = "$p smokes and chars!";
break;
case ITEM_WAND:
msg = "$p sparks and sputters!";
break;
case ITEM_FOOD:
msg = "$p blackens and crisps!";
break;
case ITEM_PILL:
msg = "$p melts and drips!";
break;
}
act (msg, victim, obj_lose, NULL, TO_CHAR);
sprintf (log_buf, "%s's %s is consumed by Fire Breath", victim->name,
obj_lose->short_descr);
if (obj_lose->contains) remove_owned (obj_lose, ch);
if (obj_lose->contains) remove_unowned (obj_lose, ch);
log_string (log_buf, NULL);
extract_obj (obj_lose);
}
}
hpch = UMAX (10, ch->hit);
dam = number_range (hpch / 16 + 1, hpch / 8);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE))
{
damage (ch, victim, (dam * 2), sn);
hp = ((hp - victim->hit) / 2) + victim->hit;
}
else
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_HEAT))
victim->hit = hp;
return;
}
void spell_frost_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
int dam;
int hpch;
int hp;
if (IS_ITEMAFF (victim, ITEMA_ICESHIELD) && number_range(1,2) == 1)
return;
if (number_percent () < 2 * level && !saves_spell (level, victim))
{
for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
{
char *msg;
obj_next = obj_lose->next_content;
if (number_bits (2) != 0)
continue;
if (IS_SET (obj_lose->quest, QUEST_SPELLPROOF))
continue;
if (IS_SET (obj_lose->quest2, QUEST2_INDEST))
continue;
switch (obj_lose->item_type)
{
default:
continue;
case ITEM_CONTAINER:
case ITEM_DRINK_CON:
case ITEM_POTION:
msg = "$p freezes and shatters!";
break;
}
if (obj_lose->contains) remove_owned (obj_lose, ch);
if (obj_lose->contains) remove_unowned (obj_lose, ch);
sprintf (log_buf, "%s's %s is consumed by Frost Breath",
victim->name, obj_lose->short_descr);
log_string (log_buf, NULL);
act (msg, victim, obj_lose, NULL, TO_CHAR);
extract_obj (obj_lose);
}
}
hpch = UMAX (10, ch->hit);
dam = number_range (hpch / 16 + 1, hpch / 8);
if (saves_spell (level, victim))
dam /= 2;
if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_VAMPIRE))
dam /= 2;
hp = victim->hit;
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_COLD))
victim->hit = hp;
return;
}
void spell_gas_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
int dam;
int hpch;
int chhp;
int number_hit = 0;
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if (number_hit > 30)
continue;
if (can_see (ch, vch))
number_hit++;
if (IS_NPC (ch) ? !IS_NPC (vch) : IS_NPC (vch))
{
hpch = UMAX (10, ch->hit);
dam = number_range (hpch / 16 + 1, hpch / 8);
if (saves_spell (level, vch))
dam /= 2;
chhp = vch->hit;
damage (ch, vch, dam, sn);
if (!IS_NPC (vch) && IS_CLASS (vch, CLASS_VAMPIRE))
vch->hit = chhp;
}
}
if (IS_CLASS (ch, CLASS_MAGE))
WAIT_STATE (ch, 8);
return;
}
void spell_lightning_breath (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hpch;
int hp;
if (IS_ITEMAFF (victim, ITEMA_SHOCKSHIELD) && number_range(1,2) == 1)
return;
hpch = UMAX (10, ch->hit);
dam = number_range (hpch / 16 + 1, hpch / 8);
if (saves_spell (level, victim))
dam /= 2;
hp = victim->hit;
damage (ch, victim, dam, sn);
if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_LIGHTNING))
victim->hit = hp;
return;
}
/* Extra spells written by KaVir. */
void spell_guardian (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
AFFECT_DATA af;
if (ch->pcdata->followers > 4)
{
send_to_char ("Nothing happens.\n\r", ch);
return;
}
ch->pcdata->followers++;
victim = create_mobile (get_mob_index (MOB_VNUM_GUARDIAN));
victim->level = level;
victim->hit = 100 * level;
victim->max_hit = 100 * level;
victim->hitroll = level;
victim->damroll = level;
victim->armor = 100 - (level * 7);
strcpy (buf, "Come forth, creature of darkness, and do my bidding!");
do_say (ch, buf);
send_to_char ("A demon bursts from the ground and bows before you.\n\r",
ch);
act ("$N bursts from the ground and bows before $n.", ch, NULL, victim,
TO_ROOM);
char_to_room (victim, ch->in_room);
add_follower (victim, ch);
af.type = sn;
af.duration = 666;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char (victim, &af);
return;
}
void spell_soulblade (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
char buf[MAX_STRING_LENGTH];
char wpnname[MAX_INPUT_LENGTH];
int weapontype;
int weaponmagic;
int armourmagic;
int value_three = 0;
weapontype = number_range (1, 12);
weaponmagic = number_range (1, 9);
armourmagic = number_range (1, 12);
obj = create_object (get_obj_index (OBJ_VNUM_SOULBLADE), 0);
if (weapontype == 1)
strcpy (wpnname, "blade");
if (weapontype == 2)
strcpy (wpnname, "dagger");
if (weapontype == 3)
strcpy (wpnname, "blade");
if (weapontype == 4)
strcpy (wpnname, "whip");
if (weapontype == 5)
strcpy (wpnname, "claw");
if (weapontype == 6)
strcpy (wpnname, "blaster");
if (weapontype == 7)
strcpy (wpnname, "club");
if (weapontype == 8)
strcpy (wpnname, "club");
if (weapontype == 9)
strcpy (wpnname, "grepper");
if (weapontype == 10)
strcpy (wpnname, "biter");
if (weapontype == 11)
strcpy (wpnname, "dagger");
if (weapontype == 12)
strcpy (wpnname, "vacuum");
if (weaponmagic == 1)
value_three = 1; /* Dripping in Acid */
else if (weaponmagic == 2)
value_three = 4; /* Blind */
else if (weaponmagic == 3)
value_three = 30; /* Dispel Evil */
else if (weaponmagic == 4)
value_three = 34; /* Vampiric */
else if (weaponmagic == 5)
value_three = 37; /* Hellfire (Fire attack) */
else if (weaponmagic == 6)
value_three = 48; /* Lightning attack */
else if (weaponmagic == 7)
value_three = 24; /* Curse */
else if (weaponmagic == 8)
value_three = 42; /* Harm */
else
value_three = 53; /* Poison */
if (armourmagic == 1)
value_three += 2000; /* See Invis */
else if (armourmagic == 2)
value_three += 3000; /* Fly */
else if (armourmagic == 3)
value_three += 1000; /* Infravision */
else if (armourmagic == 4)
value_three += 5000; /* Invis */
else if (armourmagic == 5)
value_three += 6000; /* Pass Door */
else if (armourmagic == 6)
value_three += 7000; /* Protection */
else if (armourmagic == 7)
value_three += 8000; /* Sanctuary */
else if (armourmagic == 8)
value_three += 9000; /* Sneak */
else if (armourmagic == 9)
value_three += 10000; /* Shock Shield */
else if (armourmagic == 10)
armourmagic = 11000; /* Fire Shield */
else if (armourmagic == 11)
value_three += 12000; /* Ice Shield */
else
value_three += 13000; /* Acid Shield */
/* First we name the weapon */
free_string (obj->name);
sprintf (buf, "%s soul %s", ch->name, wpnname);
obj->name = str_dup (buf);
free_string (obj->short_descr);
if (IS_NPC (ch))
sprintf (buf, "%s's soul %s", ch->short_descr, wpnname);
else
sprintf (buf, "%s's soul %s", ch->name, wpnname);
buf[0] = UPPER (buf[0]);
obj->short_descr = str_dup (buf);
free_string (obj->description);
if (IS_NPC (ch))
sprintf (buf, "%s's soul %s is lying here.", ch->short_descr, wpnname);
else
sprintf (buf, "%s's soul %s is lying here.", ch->name, wpnname);
buf[0] = UPPER (buf[0]);
obj->description = str_dup (buf);
if (IS_NPC (ch))
obj->level = ch->level;
else if (ch->spl[2] > 4)
obj->level = ch->spl[2] / 4;
else
obj->level = 1;
if (obj->level > 60)
obj->level = 60;
obj->value[0] = value_three;
obj->value[1] = 10;
obj->value[2] = 20;
obj->value[3] = weapontype;
if (obj->questmaker != NULL)
free_string (obj->questmaker);
obj->questmaker = str_dup (ch->name);
if (!IS_NPC (ch))
{
if (obj->questowner != NULL)
free_string (obj->questowner);
obj->questowner = str_dup (ch->name);
}
obj_to_char (obj, ch);
act ("$p fades into existance in your hand.", ch, obj, NULL, TO_CHAR);
act ("$p fades into existance in $n's hand.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_mana (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!IS_NPC (ch) && !IS_CLASS (ch, CLASS_VAMPIRE)
&& IS_VAMPAFF (ch, VAM_CELERITY))
{
if (ch->move < 25)
{
send_to_char ("You are too exhausted to do that.\n\r", ch);
return;
}
ch->move = ch->move - 25;
}
else
{
if (ch->move < 50)
{
send_to_char ("You are too exhausted to do that.\n\r", ch);
return;
}
ch->move = ch->move - 50;
}
victim->mana = UMIN (victim->mana + level + 10, victim->max_mana);
update_pos (ch);
update_pos (victim);
if (ch == victim)
{
send_to_char ("You draw in energy from your surrounding area.\n\r", ch);
act ("$n draws in energy from $s surrounding area.", ch, NULL, NULL,
TO_ROOM);
return;
}
act ("You draw in energy from around you and channel it into $N.", ch,
NULL, victim, TO_CHAR);
act ("$n draws in energy and channels it into $N.", ch, NULL, victim,
TO_NOTVICT);
act ("$n draws in energy and channels it into you.", ch, NULL, victim,
TO_VICT);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_frenzy (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = 1 + level / 10;
af.location = APPLY_HITROLL;
af.modifier = level / 5;
af.bitvector = 0;
affect_to_char (victim, &af);
af.location = APPLY_DAMROLL;
af.modifier = level / 5;
affect_to_char (victim, &af);
af.location = APPLY_AC;
af.modifier = -(level / 2);
affect_to_char (victim, &af);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
act ("$n is consumed with rage.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You are consumed with rage!\n\r", victim);
if (!IS_NPC (victim))
do_beastlike (victim, "");
return;
}
void spell_darkblessing (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected (victim, sn))
return;
af.type = sn;
af.duration = level / 2;
af.location = APPLY_HITROLL;
af.modifier = 1 + level / 14;
af.bitvector = 0;
affect_to_char (victim, &af);
af.location = APPLY_DAMROLL;
af.modifier = 1 + level / 14;
affect_to_char (victim, &af);
if (ch != victim)
send_to_char ("Ok.\n\r", ch);
act ("$n looks wicked.", victim, NULL, NULL, TO_ROOM);
send_to_char ("You feel wicked.\n\r", victim);
return;
}
void spell_portal (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim;
OBJ_DATA *obj;
char arg[MAX_INPUT_LENGTH];
int duration;
one_argument (target_name, arg);
if (arg[0] == '\0')
{
send_to_char ("Who do you wish to create a portal to?\n\r", ch);
return;
}
victim = get_char_world (ch, arg);
if ((victim = get_char_world (ch, target_name)) == NULL
|| victim == ch
|| victim->in_room == NULL
|| IS_NPC (ch)
|| IS_NPC (victim)
|| (IS_SET (ch->in_room->room_flags, ROOM_PRIVATE) && ch->fight_timer == 0)
|| (IS_SET (ch->in_room->room_flags, ROOM_SOLITARY) && ch->fight_timer == 0)
|| (IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL) && ch->fight_timer == 0)
|| (IS_SET (victim->in_room->room_flags, ROOM_PRIVATE) && victim->fight_timer == 0)
|| (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER)&& victim->fight_timer == 0)
|| (IS_SET (victim->in_room->room_flags, ROOM_SOLITARY) && victim->fight_timer == 0)
|| (IS_SET (victim->in_room->room_flags, ROOM_NO_RECALL) && victim->fight_timer == 0)
|| IS_SET (victim->in_room->room_flags, ROOM_GOD)
|| IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER)
|| IS_SET (ch->in_room->room_flags, ROOM_CCHAMBER)
|| victim->in_room->vnum == ch->in_room->vnum )
{
send_to_char ("You failed.\n\r", ch);
return;
}
if ( ch->fight_timer > 0 )
{
if ( victim->in_room->vnum == ROOM_VNUM_ALTAR )
{
send_to_char( "Some force rips your energy away from you before you manage to cast the spell.\n\r", ch );
ch->mana = 0;
return;
}
}
if ( victim->fight_timer > 0 )
{
if ( ch->in_room->vnum == ROOM_VNUM_ALTAR )
{
send_to_char( "Some force rips your energy away from you before you manage to cast the spell.\n\r", ch );
ch->mana = 0;
return;
}
}
if (IS_SET (victim->flag2, AFF2_INARENA))
{
stc ("They're in the arena. You are unable to portal to them.\n\r", ch);
return;
}
if (is_inarena (ch))
return;
if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
{
if (victim->fight_timer == 0)
{
stc ("You failed\n\r", ch);
return;
}
if (victim->fight_timer > 0 && (number_range (1, 100) > 50))
{
stcprintf (ch, "Success, you manage to portal to %s!\n\r",
victim->name);
stcprintf (victim,
"%s successfully portalled to you, as you have a fight timer set!\n\r",
ch->name);
}
else
{
stc ("You failed!\n\r", ch);
return;
}
}
duration = number_range (7, 9);
obj = create_object (get_obj_index (OBJ_VNUM_PORTAL), 0);
obj->value[0] = victim->in_room->vnum;
obj->value[3] = ch->in_room->vnum;
obj->timer = duration;
if (IS_AFFECTED (ch, AFF_SHADOWPLANE))
obj->extra_flags = ITEM_SHADOWPLANE;
obj_to_room (obj, ch->in_room);
obj = create_object (get_obj_index (OBJ_VNUM_PORTAL), 0);
obj->value[0] = ch->in_room->vnum;
obj->value[3] = victim->in_room->vnum;
obj->timer = duration;
if (IS_AFFECTED (victim, AFF_SHADOWPLANE))
obj->extra_flags = ITEM_SHADOWPLANE;
obj_to_room (obj, victim->in_room);
act ("$p appears in front of $n.", ch, obj, NULL, TO_ROOM);
act ("$p appears in front of you.", ch, obj, NULL, TO_CHAR);
act ("$p appears in front of $n.", victim, obj, NULL, TO_ROOM);
act ("$p appears in front of you.", ch, obj, victim, TO_VICT);
if (IS_CLASS(ch, CLASS_MAGE))
WAIT_STATE (ch, skill_table[sn].beats);
return;
}
/* This spell is designed for potions */
void spell_energyflux (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
victim->mana = UMIN (victim->mana + 1000, victim->max_mana);
update_pos (victim);
send_to_char ("You feel mana channel into your body.\n\r", victim);
return;
}
void spell_voodoo (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj;
char buf[MAX_INPUT_LENGTH];
char arg[MAX_INPUT_LENGTH];
char part1[MAX_INPUT_LENGTH];
char part2[MAX_INPUT_LENGTH];
int worn;
one_argument (target_name, arg);
victim = get_char_world (ch, arg);
if (ch->practice < 5)
{
send_to_char
("It costs 5 points of primal energy to create a voodoo doll.\n\r",
ch);
return;
}
if ((victim = get_char_world (ch, target_name)) == NULL)
{
send_to_char ("Nobody by that name is playing.\n\r", ch);
return;
}
if ((obj = get_eq_char (ch, WEAR_WIELD)) == NULL)
{
if ((obj = get_eq_char (ch, WEAR_HOLD)) == NULL)
{
if ((obj = get_eq_char (ch, WEAR_DUAL)) == NULL)
{
send_to_char ("You are not holding any body parts.\n\r", ch);
return;
}
else
worn = WEAR_DUAL;
}
else
worn = WEAR_HOLD;
}
else
worn = WEAR_WIELD;
if (IS_NPC (victim))
{
send_to_char ("Not on NPC's.\n\r", ch);
return;
}
if (obj->questmaker != NULL && strlen (obj->questmaker) > 1)
{
send_to_char ("You cannot use that item.\n\r", ch);
return;
}
if (obj->value[2] == 12)
sprintf (part1, "head %s", victim->name);
else if (obj->value[2] == 13)
sprintf (part1, "heart %s", victim->name);
else if (obj->value[2] == 14)
sprintf (part1, "arm %s", victim->name);
else if (obj->value[2] == 15)
sprintf (part1, "leg %s", victim->name);
else if (obj->value[2] == 30004)
sprintf (part1, "entrails %s", victim->name);
else if (obj->value[2] == 30005)
sprintf (part1, "brain %s", victim->name);
else if (obj->value[2] == 30006)
sprintf (part1, "eye eyeball %s", victim->name);
else if (obj->value[2] == 30012)
sprintf (part1, "face %s", victim->name);
else if (obj->value[2] == 30013)
sprintf (part1, "windpipe %s", victim->name);
else if (obj->value[2] == 30014)
sprintf (part1, "cracked head %s", victim->name);
else if (obj->value[2] == 30025)
sprintf (part1, "ear %s", victim->name);
else if (obj->value[2] == 30026)
sprintf (part1, "nose %s", victim->name);
else if (obj->value[2] == 30027)
sprintf (part1, "tooth %s", victim->name);
else if (obj->value[2] == 30028)
sprintf (part1, "tongue %s", victim->name);
else if (obj->value[2] == 30029)
sprintf (part1, "hand %s", victim->name);
else if (obj->value[2] == 30030)
sprintf (part1, "foot %s", victim->name);
else if (obj->value[2] == 30031)
sprintf (part1, "thumb %s", victim->name);
else if (obj->value[2] == 30032)
sprintf (part1, "index finger %s", victim->name);
else if (obj->value[2] == 30033)
sprintf (part1, "middle finger %s", victim->name);
else if (obj->value[2] == 30034)
sprintf (part1, "ring finger %s", victim->name);
else if (obj->value[2] == 30035)
sprintf (part1, "little finger %s", victim->name);
else if (obj->value[2] == 30036)
sprintf (part1, "toe %s", victim->name);
else
{
sprintf (buf, "%s isn't a part of %s!\n\r", obj->name, victim->name);
send_to_char (buf, ch);
return;
}
sprintf (part2, obj->name);
if (str_cmp (part1, part2))
{
sprintf (buf, "But you are holding %s, not %s!\n\r", obj->short_descr,
victim->name);
send_to_char (buf, ch);
return;
}
act ("$p vanishes from your hand in a puff of smoke.", ch, obj, NULL,
TO_CHAR);
act ("$p vanishes from $n's hand in a puff of smoke.", ch, obj, NULL,
TO_ROOM);
obj_from_char (obj);
extract_obj (obj);
obj = create_object (get_obj_index (OBJ_VNUM_VOODOO_DOLL), 0);
sprintf (buf, "%s voodoo doll", victim->name);
free_string (obj->name);
obj->name = str_dup (buf);
sprintf (buf, "a voodoo doll of %s", victim->name);
free_string (obj->short_descr);
obj->short_descr = str_dup (buf);
sprintf (buf, "A voodoo doll of %s lies here.", victim->name);
free_string (obj->description);
obj->description = str_dup (buf);
obj_to_char (obj, ch);
equip_char (ch, obj, worn);
act ("$p appears in your hand.", ch, obj, NULL, TO_CHAR);
act ("$p appears in $n's hand.", ch, obj, NULL, TO_ROOM);
ch->practice -= 5;
return;
}
void spell_tendrils (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
if (IS_NPC (ch) || !IS_CLASS (ch, CLASS_VAMPIRE))
return;
dam = number_range (1, 10) * get_disc(ch, VAM_SERP) * level;
if (is_safe (ch, victim))
return;
if (victim->in_room->vnum == ROOM_VNUM_ALTAR)
return;
send_to_char ("Tendrils of darkness shoot from your fingertips.\n\r", ch);
act ("Tendrils of darkness shoot from $n's fingertips.", ch, NULL, NULL,
TO_ROOM);
if (saves_spell (level, victim) && victim->position >= POS_FIGHTING)
{
dam = 0;
damage (ch, victim, dam, sn);
return;
}
damage (ch, victim, dam, sn);
if (victim == NULL || victim->position == POS_DEAD)
return;
if (IS_SET (victim->flag2, AFF2_TENDRILS))
return;
af.type = sn;
af.location = APPLY_AC;
af.modifier = 200;
af.duration = number_range (1, 2);
af.bitvector = AFF2_TENDRILS;
// affect_to_char (victim, &af);
SET_BIT(victim->flag2, AFF2_TENDRILS);
send_to_char ("You are entrapped by tendrils of darkness!\n\r", victim);
act ("$n is entrapped by tendrils of darkness!", victim, NULL, NULL,
TO_ROOM);
return;
}
void spell_entrails (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
if (IS_NPC (ch))
return;
dam = number_range (2, 10) * level;
if (is_safe (ch, victim))
return;
if (victim->in_room->vnum == ROOM_VNUM_ALTAR)
return;
send_to_char ("Entrails shoot from your stomach.\n\r", ch);
act ("Entrails shoot from $n's stomach.", ch, NULL, NULL, TO_ROOM);
/*
if (saves_spell (level, victim) && victim->position >= POS_FIGHTING)
{
send_to_char ("You dodge the entrails!\n\r", victim);
act ("$n dodges the entrails!", victim, NULL, NULL, TO_ROOM);
dam = 0;
damage (ch, victim, dam, sn);
return;
}
*/
damage (ch, victim, dam, sn);
if (victim == NULL || victim->position == POS_DEAD)
return;
if (IS_SET (victim->affected_by, AFF_ENTRAILS))
return;
af.type = sn;
af.location = APPLY_AC;
af.modifier = 100;
af.duration = number_range (1, 2);
af.bitvector = AFF_ENTRAILS;
affect_to_char (victim, &af);
if (number_range (1, 10) == 1
&& !IS_SET (victim->affected_by, AFF_ENTRAILS))
{
SET_BIT (victim->affected_by, AFF_ENTRAILS);
send_to_char
("The entrails form into restraining bands around your body.\n\r",
victim);
act ("The entrails into restraining bands around $n's body.", victim,
NULL, NULL, TO_ROOM);
}
return;
}
void spell_transport (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
CHAR_DATA *victim;
char log_buf[MSL];
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (arg1[0] == '\0')
{
send_to_char ("Transport which object?\n\r", ch);
return;
}
if (arg2[0] == '\0')
{
send_to_char ("Transport who whom?\n\r", ch);
return;
}
if ((victim = get_char_world_noabbr (ch, arg2)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (ch == victim)
{
stc ("Why, you already have it!\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that item.\n\r", ch);
return;
}
if (ch->fight_timer > 0)
{
stc ("You can no longer tranport items with a fight timer!\n\r", ch);
return;
}
if (IS_NPC (victim) && (victim->pIndexData->vnum == 3145))
{
stc ("You are unable to transport anything to them.\n\r", ch);
return;
}
if (IS_SET (obj->quest, QUEST_ARTIFACT))
{
stc ("Your Magic isnt powerful enough to transport artifacts!\n\r", ch);
return;
}
if (obj->item_type == ITEM_PIECE)
{
stc ("You cant seem to let go of it\n\r", ch);
return;
}
if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_TRANSPORT))
{
send_to_char ("You are unable to transport anything to them.\n\r", ch);
return;
}
if (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER))
{
stc ("You failed.\n\r", ch);
return;
}
if (IS_NPC (victim) && IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
{
stc ("You are unable to transport anything to them.\n\r", ch);
return;
}
if (IS_SET (victim->in_room->room_flags, ROOM_GOD))
{
send_to_char ("You failed.\n\r", ch);
return;
}
// Same as arti but for STOKENS
if (obj->item_type == ITEM_STOKEN)
{
OBJ_DATA *token;
for (token = victim->carrying; token; token = token->next_content)
{
if (token->item_type == ITEM_STOKEN)
{
stc ("They already have a Status Token on them\n\r", ch);
return;
}
}
}
if (!IS_NPC (victim) && obj->item_type == ITEM_PIECE && ch->level < 3)
{
stc ("They are not powerfull enough for an artifact\n\r", ch);
return;
}
if (IS_SET (obj->quest, QUEST_ARTIFACT))
{
OBJ_DATA *arti;
for (arti = victim->carrying; arti; arti = arti->next_content)
{
if (IS_SET (arti->quest, QUEST_ARTIFACT))
{
char buf[MSL];
sprintf (buf, "%s will not tolerate the proximity of %s.\n\r",
obj->short_descr, arti->short_descr);
stc (buf, ch);
return;
}
}
} // end one arti at a time
act ("$p vanishes from your hands in an swirl of smoke.", ch, obj, NULL,
TO_CHAR);
act ("$p vanishes from $n's hands in a swirl of smoke.", ch, obj, NULL,
TO_ROOM);
obj_from_char (obj);
obj_to_char (obj, victim);
act ("$p appears in your hands in an swirl of smoke.", victim, obj, NULL,
TO_CHAR);
act ("$p appears in $n's hands in an swirl of smoke.", victim, obj, NULL,
TO_ROOM);
do_autosave (ch, "");
do_autosave (victim, "");
sprintf (log_buf, "%s transported %s to %s.", ch->name, obj->short_descr,
victim->name);
log_string_sil (log_buf);
wiznet (ch, WIZ_TRANS, get_trust (ch), log_buf);
return;
}
void spell_regenerate (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
CHAR_DATA *victim;
int teeth = 0;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (arg1[0] == '\0')
{
send_to_char ("Regenerate which person?\n\r", ch);
return;
}
if ((victim = get_char_room (ch, arg1)) == NULL)
{
send_to_char ("They aren't here.\n\r", ch);
return;
}
if (victim->loc_hp[6] > 0)
{
send_to_char
("You cannot regenerate someone who is still bleeding.\n\r", ch);
return;
}
if (arg2[0] == '\0' || (obj = get_obj_carry (ch, arg2)) == NULL)
{
if (!ch->fight_timer && !victim->fight_timer)
{
if (ch == victim)
send_to_char
("You chant, giving attention to all your sore areas.\n\r", ch);
else
{
act ("You chant, giving attention to the aches of $N.", ch, NULL, victim,
TO_CHAR);
act ("$n chants, giving attention to all of your sore areas in turn.", ch, NULL, victim,
TO_VICT);
}
act ("$n chants while looking intently at $N.", ch, NULL, victim,
TO_NOTVICT);
reg_mend(victim);
}
else if (arg2[0] == '\0')
{
send_to_char ("Which body part?\n\r", ch);
return;
}
else send_to_char ("You are not carrying that item.\n\r", ch);
return;
}
if (IS_HEAD (victim, LOST_TOOTH_1))
teeth += 1;
if (IS_HEAD (victim, LOST_TOOTH_2))
teeth += 2;
if (IS_HEAD (victim, LOST_TOOTH_4))
teeth += 4;
if (IS_HEAD (victim, LOST_TOOTH_8))
teeth += 8;
if (IS_HEAD (victim, LOST_TOOTH_16))
teeth += 16;
if (obj->pIndexData->vnum == OBJ_VNUM_SLICED_ARM)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_ARM))
{
send_to_char ("They don't need an arm.\n\r", ch);
return;
}
if (IS_ARM_L (victim, LOST_ARM))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_ARM);
else if (IS_ARM_R (victim, LOST_ARM))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_ARM);
act ("You press $p onto the stump of $N's shoulder.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the stump of $N's shoulder.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the stump of your shoulder.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SLICED_LEG)
{
if (!IS_LEG_L (victim, LOST_LEG) && !IS_LEG_R (victim, LOST_LEG))
{
send_to_char ("They don't need a leg.\n\r", ch);
return;
}
if (IS_LEG_L (victim, LOST_LEG))
REMOVE_BIT (victim->loc_hp[LOC_LEG_L], LOST_LEG);
else if (IS_LEG_R (victim, LOST_LEG))
REMOVE_BIT (victim->loc_hp[LOC_LEG_R], LOST_LEG);
act ("You press $p onto the stump of $N's hip.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the stump of $N's hip.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the stump of your hip.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SQUIDGY_EYEBALL)
{
if (!IS_HEAD (victim, LOST_EYE_L) && !IS_HEAD (victim, LOST_EYE_R))
{
send_to_char ("They don't need an eye.\n\r", ch);
return;
}
if (IS_HEAD (victim, LOST_EYE_L))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_EYE_L);
else if (IS_HEAD (victim, LOST_EYE_R))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_EYE_R);
act ("You press $p into $N's empty eye socket.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p into $N's empty eye socket.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p into your empty eye socket.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SLICED_EAR)
{
if (!IS_HEAD (victim, LOST_EAR_L) && !IS_HEAD (victim, LOST_EAR_R))
{
send_to_char ("They don't need an ear.\n\r", ch);
return;
}
if (IS_HEAD (victim, LOST_EAR_L))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_EAR_L);
else if (IS_HEAD (victim, LOST_EAR_R))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_EAR_R);
act ("You press $p onto the side of $N's head.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the side of $N's head.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the side of your head.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SLICED_NOSE)
{
if (!IS_HEAD (victim, LOST_NOSE))
{
send_to_char ("They don't need a nose.\n\r", ch);
return;
}
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_NOSE);
act ("You press $p onto the front of $N's face.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the front of $N's face.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the front of your face.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_HAND)
{
if (!IS_ARM_L (victim, LOST_ARM) && IS_ARM_L (victim, LOST_HAND))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_HAND);
else if (!IS_ARM_R (victim, LOST_ARM) && IS_ARM_R (victim, LOST_HAND))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_HAND);
else
{
send_to_char ("They don't need a hand.\n\r", ch);
return;
}
act ("You press $p onto the stump of $N's wrist.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the stump of $N's wrist.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the stump of your wrist.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_FOOT)
{
if (!IS_LEG_L (victim, LOST_LEG) && IS_LEG_L (victim, LOST_FOOT))
REMOVE_BIT (victim->loc_hp[LOC_LEG_L], LOST_FOOT);
else if (!IS_LEG_R (victim, LOST_LEG) && IS_LEG_R (victim, LOST_FOOT))
REMOVE_BIT (victim->loc_hp[LOC_LEG_R], LOST_FOOT);
else
{
send_to_char ("They don't need a foot.\n\r", ch);
return;
}
act ("You press $p onto the stump of $N's ankle.", ch, obj, victim,
TO_CHAR);
act ("$n presses $p onto the stump of $N's ankle.", ch, obj, victim,
TO_NOTVICT);
act ("$n presses $p onto the stump of your ankle.", ch, obj, victim,
TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_THUMB)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_L (victim, LOST_HAND)
&& IS_ARM_L (victim, LOST_THUMB))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_THUMB);
else if (!IS_ARM_R (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_HAND)
&& IS_ARM_R (victim, LOST_THUMB))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_THUMB);
else
{
send_to_char ("They don't need a thumb.\n\r", ch);
return;
}
act ("You press $p onto $N's hand.", ch, obj, victim, TO_CHAR);
act ("$n presses $p onto $N's hand.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p onto your hand.", ch, obj, victim, TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_INDEX)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_L (victim, LOST_HAND)
&& IS_ARM_L (victim, LOST_FINGER_I))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_FINGER_I);
else if (!IS_ARM_R (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_HAND)
&& IS_ARM_R (victim, LOST_FINGER_I))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_FINGER_I);
else
{
send_to_char ("They don't need an index finger.\n\r", ch);
return;
}
act ("You press $p onto $N's hand.", ch, obj, victim, TO_CHAR);
act ("$n presses $p onto $N's hand.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p onto your hand.", ch, obj, victim, TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_MIDDLE)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_L (victim, LOST_HAND)
&& IS_ARM_L (victim, LOST_FINGER_M))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_FINGER_M);
else if (!IS_ARM_R (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_HAND)
&& IS_ARM_R (victim, LOST_FINGER_M))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_FINGER_M);
else
{
send_to_char ("They don't need a middle finger.\n\r", ch);
return;
}
act ("You press $p onto $N's hand.", ch, obj, victim, TO_CHAR);
act ("$n presses $p onto $N's hand.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p onto your hand.", ch, obj, victim, TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_RING)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_L (victim, LOST_HAND)
&& IS_ARM_L (victim, LOST_FINGER_R))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_FINGER_R);
else if (!IS_ARM_R (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_HAND)
&& IS_ARM_R (victim, LOST_FINGER_R))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_FINGER_R);
else
{
send_to_char ("They don't need a ring finger.\n\r", ch);
return;
}
act ("You press $p onto $N's hand.", ch, obj, victim, TO_CHAR);
act ("$n presses $p onto $N's hand.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p onto your hand.", ch, obj, victim, TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_SEVERED_LITTLE)
{
if (!IS_ARM_L (victim, LOST_ARM) && !IS_ARM_L (victim, LOST_HAND)
&& IS_ARM_L (victim, LOST_FINGER_L))
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], LOST_FINGER_L);
else if (!IS_ARM_R (victim, LOST_ARM) && !IS_ARM_R (victim, LOST_HAND)
&& IS_ARM_R (victim, LOST_FINGER_L))
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], LOST_FINGER_L);
else
{
send_to_char ("They don't need a little finger.\n\r", ch);
return;
}
act ("You press $p onto $N's hand.", ch, obj, victim, TO_CHAR);
act ("$n presses $p onto $N's hand.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p onto your hand.", ch, obj, victim, TO_VICT);
extract_obj (obj);
return;
}
else if (obj->pIndexData->vnum == OBJ_VNUM_KNOCKED_TOOTH && teeth > 0)
{
if (IS_HEAD (victim, LOST_TOOTH_1))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_1);
if (IS_HEAD (victim, LOST_TOOTH_2))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_2);
if (IS_HEAD (victim, LOST_TOOTH_4))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_4);
if (IS_HEAD (victim, LOST_TOOTH_8))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_8);
if (IS_HEAD (victim, LOST_TOOTH_16))
REMOVE_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_16);
teeth -= 1;
if (teeth >= 16)
{
teeth -= 16;
SET_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_16);
}
if (teeth >= 8)
{
teeth -= 8;
SET_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_8);
}
if (teeth >= 4)
{
teeth -= 4;
SET_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_4);
}
if (teeth >= 2)
{
teeth -= 2;
SET_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_2);
}
if (teeth >= 1)
{
teeth -= 1;
SET_BIT (victim->loc_hp[LOC_HEAD], LOST_TOOTH_1);
}
act ("You press $p into $N's mouth.", ch, obj, victim, TO_CHAR);
act ("$n presses $p into $N's mouth.", ch, obj, victim, TO_NOTVICT);
act ("$n presses $p into your mouth.", ch, obj, victim, TO_VICT);
extract_obj (obj);
}
else
{
act ("There is nowhere to stick $p on $N.", ch, obj, victim, TO_CHAR);
return;
}
return;
}
void spell_clot (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (IS_BLEEDING (victim, BLEEDING_HEAD))
{
act ("$n's head stops bleeding.", victim, NULL, NULL, TO_ROOM);
act ("Your head stops bleeding.", victim, NULL, NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_HEAD);
}
else if (IS_BLEEDING (victim, BLEEDING_THROAT))
{
act ("$n's throat stops bleeding.", victim, NULL, NULL, TO_ROOM);
act ("Your throat stops bleeding.", victim, NULL, NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_THROAT);
}
else if (IS_BLEEDING (victim, BLEEDING_ARM_L))
{
act ("The stump of $n's left arm stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your left arm stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_ARM_L);
}
else if (IS_BLEEDING (victim, BLEEDING_ARM_R))
{
act ("The stump of $n's right arm stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your right arm stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_ARM_R);
}
else if (IS_BLEEDING (victim, BLEEDING_LEG_L))
{
act ("The stump of $n's left leg stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your left leg stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_LEG_L);
}
else if (IS_BLEEDING (victim, BLEEDING_LEG_R))
{
act ("The stump of $n's right leg stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your right leg stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_LEG_R);
}
else if (IS_BLEEDING (victim, BLEEDING_HAND_L))
{
act ("The stump of $n's left wrist stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your left wrist stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_HAND_L);
}
else if (IS_BLEEDING (victim, BLEEDING_HAND_R))
{
act ("The stump of $n's right wrist stops bleeding.", victim, NULL,
NULL, TO_ROOM);
act ("The stump of your right wrist stops bleeding.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_HAND_R);
}
else if (IS_BLEEDING (victim, BLEEDING_FOOT_L))
{
act ("The stump of $n's left ankle stops bleeding.", victim, NULL, NULL,
TO_ROOM);
act ("The stump of your left ankle stops bleeding.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_FOOT_L);
}
else if (IS_BLEEDING (victim, BLEEDING_FOOT_R))
{
act ("The stump of $n's right ankle stops bleeding.", victim, NULL,
NULL, TO_ROOM);
act ("The stump of your right ankle stops bleeding.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[6], BLEEDING_FOOT_R);
}
else
send_to_char ("They have no wounds to clot.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_mend (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int ribs = 0;
if (IS_BODY (victim, BROKEN_RIBS_1))
ribs += 1;
if (IS_BODY (victim, BROKEN_RIBS_2))
ribs += 2;
if (IS_BODY (victim, BROKEN_RIBS_4))
ribs += 4;
if (IS_BODY (victim, BROKEN_RIBS_8))
ribs += 8;
if (IS_BODY (victim, BROKEN_RIBS_16))
ribs += 16;
if (ribs > 0)
{
if (IS_BODY (victim, BROKEN_RIBS_1))
REMOVE_BIT (victim->loc_hp[1], BROKEN_RIBS_1);
if (IS_BODY (victim, BROKEN_RIBS_2))
REMOVE_BIT (victim->loc_hp[1], BROKEN_RIBS_2);
if (IS_BODY (victim, BROKEN_RIBS_4))
REMOVE_BIT (victim->loc_hp[1], BROKEN_RIBS_4);
if (IS_BODY (victim, BROKEN_RIBS_8))
REMOVE_BIT (victim->loc_hp[1], BROKEN_RIBS_8);
if (IS_BODY (victim, BROKEN_RIBS_16))
REMOVE_BIT (victim->loc_hp[1], BROKEN_RIBS_16);
ribs -= 1;
if (ribs >= 16)
{
ribs -= 16;
SET_BIT (victim->loc_hp[1], BROKEN_RIBS_16);
}
if (ribs >= 8)
{
ribs -= 8;
SET_BIT (victim->loc_hp[1], BROKEN_RIBS_8);
}
if (ribs >= 4)
{
ribs -= 4;
SET_BIT (victim->loc_hp[1], BROKEN_RIBS_4);
}
if (ribs >= 2)
{
ribs -= 2;
SET_BIT (victim->loc_hp[1], BROKEN_RIBS_2);
}
if (ribs >= 1)
{
ribs -= 1;
SET_BIT (victim->loc_hp[1], BROKEN_RIBS_1);
}
act ("One of $n's ribs snap back into place.", victim, NULL, NULL,
TO_ROOM);
act ("One of your ribs snap back into place.", victim, NULL, NULL,
TO_CHAR);
}
else if (IS_HEAD (victim, BROKEN_NOSE) && !IS_HEAD (victim, LOST_NOSE))
{
act ("$n's nose snaps back into place.", victim, NULL, NULL, TO_ROOM);
act ("Your nose snaps back into place.", victim, NULL, NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_HEAD], BROKEN_NOSE);
}
else if (IS_HEAD (victim, BROKEN_JAW))
{
act ("$n's jaw snaps back into place.", victim, NULL, NULL, TO_ROOM);
act ("Your jaw snaps back into place.", victim, NULL, NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_HEAD], BROKEN_JAW);
}
else if (IS_HEAD (victim, BROKEN_SKULL))
{
act ("$n's skull knits itself back together.", victim, NULL, NULL,
TO_ROOM);
act ("Your skull knits itself back together.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_HEAD], BROKEN_SKULL);
}
else if (IS_BODY (victim, BROKEN_SPINE))
{
act ("$n's spine knits itself back together.", victim, NULL, NULL,
TO_ROOM);
act ("Your spine knits itself back together.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_BODY], BROKEN_SPINE);
}
else if (IS_BODY (victim, BROKEN_NECK))
{
act ("$n's neck snaps back into place.", victim, NULL, NULL, TO_ROOM);
act ("Your neck snaps back into place.", victim, NULL, NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_BODY], BROKEN_NECK);
}
else if (IS_ARM_L (victim, BROKEN_ARM) && !IS_ARM_L (victim, LOST_ARM))
{
act ("$n's left arm snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your left arm snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_ARM);
}
else if (IS_ARM_R (victim, BROKEN_ARM) && !IS_ARM_R (victim, LOST_ARM))
{
act ("$n's right arm snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your right arm snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_ARM);
}
else if (IS_LEG_L (victim, BROKEN_LEG) && !IS_LEG_L (victim, LOST_LEG))
{
act ("$n's left leg snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your left leg snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_LEG_L], BROKEN_LEG);
}
else if (IS_LEG_R (victim, BROKEN_LEG) && !IS_LEG_R (victim, LOST_LEG))
{
act ("$n's right leg snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your right leg snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_LEG_R], BROKEN_LEG);
}
else if (IS_ARM_L (victim, BROKEN_THUMB) && !IS_ARM_L (victim, LOST_ARM)
&& !IS_ARM_L (victim, LOST_HAND)
&& !IS_ARM_L (victim, LOST_THUMB))
{
act ("$n's left thumb snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your left thumb snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_THUMB);
}
else if (IS_ARM_L (victim, BROKEN_FINGER_I) && !IS_ARM_L (victim, LOST_ARM)
&& !IS_ARM_L (victim, LOST_HAND)
&& !IS_ARM_L (victim, LOST_FINGER_I))
{
act ("$n's left index finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your left index finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_FINGER_I);
}
else if (IS_ARM_L (victim, BROKEN_FINGER_M) && !IS_ARM_L (victim, LOST_ARM)
&& !IS_ARM_L (victim, LOST_HAND)
&& !IS_ARM_L (victim, LOST_FINGER_M))
{
act ("$n's left middle finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your left middle finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_FINGER_M);
}
else if (IS_ARM_L (victim, BROKEN_FINGER_R) && !IS_ARM_L (victim, LOST_ARM)
&& !IS_ARM_L (victim, LOST_HAND)
&& !IS_ARM_L (victim, LOST_FINGER_R))
{
act ("$n's left ring finger snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your left ring finger snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_FINGER_R);
}
else if (IS_ARM_L (victim, BROKEN_FINGER_L) && !IS_ARM_L (victim, LOST_ARM)
&& !IS_ARM_L (victim, LOST_HAND)
&& !IS_ARM_L (victim, LOST_FINGER_L))
{
act ("$n's left little finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your left little finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_L], BROKEN_FINGER_L);
}
else if (IS_ARM_R (victim, BROKEN_THUMB) && !IS_ARM_R (victim, LOST_ARM)
&& !IS_ARM_R (victim, LOST_HAND)
&& !IS_ARM_R (victim, LOST_THUMB))
{
act ("$n's right thumb snaps back into place.", victim, NULL, NULL,
TO_ROOM);
act ("Your right thumb snaps back into place.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_THUMB);
}
else if (IS_ARM_R (victim, BROKEN_FINGER_I) && !IS_ARM_R (victim, LOST_ARM)
&& !IS_ARM_R (victim, LOST_HAND)
&& !IS_ARM_R (victim, LOST_FINGER_I))
{
act ("$n's right index finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your right index finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_FINGER_I);
}
else if (IS_ARM_R (victim, BROKEN_FINGER_M) && !IS_ARM_R (victim, LOST_ARM)
&& !IS_ARM_R (victim, LOST_HAND)
&& !IS_ARM_R (victim, LOST_FINGER_M))
{
act ("$n's right middle finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your right middle finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_FINGER_M);
}
else if (IS_ARM_R (victim, BROKEN_FINGER_R) && !IS_ARM_R (victim, LOST_ARM)
&& !IS_ARM_R (victim, LOST_HAND)
&& !IS_ARM_R (victim, LOST_FINGER_R))
{
act ("$n's right ring finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your right ring finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_FINGER_R);
}
else if (IS_ARM_R (victim, BROKEN_FINGER_L) && !IS_ARM_R (victim, LOST_ARM)
&& !IS_ARM_R (victim, LOST_HAND)
&& !IS_ARM_R (victim, LOST_FINGER_L))
{
act ("$n's right little finger snaps back into place.", victim, NULL,
NULL, TO_ROOM);
act ("Your right little finger snaps back into place.", victim, NULL,
NULL, TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_ARM_R], BROKEN_FINGER_L);
}
else if (IS_BODY (victim, CUT_THROAT))
{
if (IS_SET (victim->loc_hp[6], BLEEDING_THROAT))
{
send_to_char ("But their throat is still bleeding!\n\r", ch);
return;
}
act ("The wound in $n's throat closes up.", victim, NULL, NULL,
TO_ROOM);
act ("The wound in your throat closes up.", victim, NULL, NULL,
TO_CHAR);
REMOVE_BIT (victim->loc_hp[LOC_BODY], CUT_THROAT);
}
else
send_to_char ("They have no bones to mend.\n\r", ch);
if (!IS_NPC (ch) && ch != victim)
do_humanity (ch, "");
return;
}
void spell_quest (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_INDEX_DATA *pObjIndex;
OBJ_DATA *obj;
if (ch->practice < 1)
{
send_to_char
("It costs at least 1 point of primal energy to create a quest card.\n\r",
ch);
return;
}
if ((pObjIndex = get_obj_index (OBJ_VNUM_QUESTCARD)) == NULL)
{
send_to_char ("Missing object, please inform KaVir.\n\r", ch);
return;
}
if (ch->in_room == NULL)
return;
obj = create_object (pObjIndex, 0);
obj_to_char (obj, ch);
quest_object (ch, obj);
if (ch->practice >= 100)
{
ch->practice -= 100;
obj->level = 100;
}
else
{
obj->level = ch->practice;
ch->practice = 0;
}
act ("$p fades into existance in your hands.", ch, obj, NULL, TO_CHAR);
act ("$p fades into existance in $n's hands.", ch, obj, NULL, TO_ROOM);
if (obj->questmaker != NULL)
free_string (obj->questmaker);
obj->questmaker = str_dup (ch->name);
if (obj->questowner != NULL)
free_string (obj->questowner);
obj->questowner = str_dup (ch->name);
return;
}
void spell_minor_creation (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj;
char arg[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char itemkind[10];
int itemtype;
target_name = one_argument (target_name, arg);
if (!str_cmp (arg, "potion"))
{
itemtype = ITEM_POTION;
sprintf (itemkind, "potion");
}
else if (!str_cmp (arg, "scroll"))
{
itemtype = ITEM_SCROLL;
sprintf (itemkind, "scroll");
}
else if (!str_cmp (arg, "wand"))
{
itemtype = ITEM_WAND;
sprintf (itemkind, "wand");
}
else if (!str_cmp (arg, "staff"))
{
itemtype = ITEM_STAFF;
sprintf (itemkind, "staff");
}
else if (!str_cmp (arg, "pill"))
{
itemtype = ITEM_PILL;
sprintf (itemkind, "pill");
}
else
{
send_to_char
("Item can be one of: Potion, Scroll, Wand, Staff or Pill.\n\r", ch);
return;
}
obj = create_object (get_obj_index (OBJ_VNUM_PROTOPLASM), 0);
obj->item_type = itemtype;
sprintf (buf, "%s %s", ch->name, itemkind);
free_string (obj->name);
obj->name = str_dup (buf);
sprintf (buf, "%s's %s", ch->name, itemkind);
free_string (obj->short_descr);
obj->short_descr = str_dup (buf);
sprintf (buf, "%s's %s lies here.", ch->name, itemkind);
free_string (obj->description);
obj->description = str_dup (buf);
obj->weight = 10;
if (obj->questmaker != NULL)
free_string (obj->questmaker);
obj->questmaker = str_dup (ch->name);
obj_to_char (obj, ch);
act ("$p suddenly appears in your hands.", ch, obj, NULL, TO_CHAR);
act ("$p suddenly appears in $n's hands.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_brew (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char col[10];
OBJ_DATA *obj;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("What spell do you wish to brew, and on what?\n\r", ch);
return;
}
if (((sn = skill_lookup (arg2)) == 69))
{
stc ("Nope you cant do that.\n\r", ch);
return;
}
if ((sn = skill_lookup (arg2)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (ch->pcdata->learned[sn] < 100)
{
send_to_char ("You are not adept at that spell.\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
if (obj->item_type != ITEM_POTION)
{
send_to_char ("That is not a potion.\n\r", ch);
return;
}
if (obj->value[0] != 0 || obj->value[1] != 0 || obj->value[2] != 0
|| obj->value[3] != 0)
{
send_to_char ("You need an empty potion bottle.\n\r", ch);
return;
}
if (skill_table[sn].target == 0)
{
obj->value[0] = ch->spl[0] / 4;
sprintf (col, "purple");
}
else if (skill_table[sn].target == 1)
{
obj->value[0] = ch->spl[1] / 4;
sprintf (col, "red");
}
else if (skill_table[sn].target == 2)
{
obj->value[0] = ch->spl[2] / 4;
sprintf (col, "blue");
}
else if (skill_table[sn].target == 3)
{
obj->value[0] = ch->spl[3] / 4;
sprintf (col, "green");
}
else if (skill_table[sn].target == 4)
{
obj->value[0] = ch->spl[4] / 4;
sprintf (col, "yellow");
}
else
{
send_to_char ("Oh dear...big bug...please inform KaVir.\n\r", ch);
return;
}
obj->value[1] = sn;
if (obj->value[0] >= 25)
obj->value[2] = sn;
else
obj->value[2] = -1;
if (obj->value[0] >= 50)
obj->value[3] = sn;
else
obj->value[3] = -1;
free_string (obj->name);
sprintf (buf, "%s potion %s %s", ch->name, col, skill_table[sn].name);
obj->name = str_dup (buf);
free_string (obj->short_descr);
sprintf (buf, "%s's %s potion of %s", ch->name, col, skill_table[sn].name);
obj->short_descr = str_dup (buf);
free_string (obj->description);
sprintf (buf, "A %s potion is lying here.", col);
obj->description = str_dup (buf);
act ("You brew $p.", ch, obj, NULL, TO_CHAR);
act ("$n brews $p.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_scribe (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char col[10];
OBJ_DATA *obj;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("What spell do you wish to scribe, and on what?\n\r", ch);
return;
}
if (((sn = skill_lookup (arg2)) == 69))
{
stc ("Nope you cant do that.\n\r", ch);
return;
}
if ((sn = skill_lookup (arg2)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (ch->pcdata->learned[sn] < 100)
{
send_to_char ("You are not adept at that spell.\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
if (obj->item_type != ITEM_SCROLL)
{
send_to_char ("That is not a scroll.\n\r", ch);
return;
}
if (obj->value[0] != 0 || obj->value[1] != 0 || obj->value[2] != 0
|| obj->value[3] != 0)
{
send_to_char ("You need an empty scroll parchment.\n\r", ch);
return;
}
if (skill_table[sn].target == 0)
{
obj->value[0] = ch->spl[0] / 4;
sprintf (col, "purple");
}
else if (skill_table[sn].target == 1)
{
obj->value[0] = ch->spl[1] / 4;
sprintf (col, "red");
}
else if (skill_table[sn].target == 2)
{
obj->value[0] = ch->spl[2] / 4;
sprintf (col, "blue");
}
else if (skill_table[sn].target == 3)
{
obj->value[0] = ch->spl[3] / 4;
sprintf (col, "green");
}
else if (skill_table[sn].target == 4)
{
obj->value[0] = ch->spl[4] / 4;
sprintf (col, "yellow");
}
else
{
send_to_char ("Oh dear...big bug...please inform KaVir.\n\r", ch);
return;
}
obj->value[1] = sn;
if (obj->value[0] >= 25)
obj->value[2] = sn;
else
obj->value[2] = -1;
if (obj->value[0] >= 50)
obj->value[3] = sn;
else
obj->value[3] = -1;
free_string (obj->name);
sprintf (buf, "%s scroll %s %s", ch->name, col, skill_table[sn].name);
obj->name = str_dup (buf);
free_string (obj->short_descr);
sprintf (buf, "%s's %s scroll of %s", ch->name, col, skill_table[sn].name);
obj->short_descr = str_dup (buf);
free_string (obj->description);
sprintf (buf, "A %s scroll is lying here.", col);
obj->description = str_dup (buf);
act ("You scribe $p.", ch, obj, NULL, TO_CHAR);
act ("$n scribes $p.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_carve (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char col[10];
OBJ_DATA *obj;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("What spell do you wish to carve, and on what?\n\r", ch);
return;
}
if (((sn = skill_lookup (arg2)) == 69))
{
stc ("Nope you cant do that.\n\r", ch);
return;
}
if ((sn = skill_lookup (arg2)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (ch->pcdata->learned[sn] < 100)
{
send_to_char ("You are not adept at that spell.\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
if (obj->item_type != ITEM_WAND)
{
send_to_char ("That is not a wand.\n\r", ch);
return;
}
if (obj->value[0] != 0 || obj->value[1] != 0 || obj->value[2] != 0
|| obj->value[3] != 0)
{
send_to_char ("You need an unenchanted wand.\n\r", ch);
return;
}
if (skill_table[sn].target == 0)
{
obj->value[0] = ch->spl[0] / 4;
sprintf (col, "purple");
}
else if (skill_table[sn].target == 1)
{
obj->value[0] = ch->spl[1] / 4;
sprintf (col, "red");
}
else if (skill_table[sn].target == 2)
{
obj->value[0] = ch->spl[2] / 4;
sprintf (col, "blue");
}
else if (skill_table[sn].target == 3)
{
obj->value[0] = ch->spl[3] / 4;
sprintf (col, "green");
}
else if (skill_table[sn].target == 4)
{
obj->value[0] = ch->spl[4] / 4;
sprintf (col, "yellow");
}
else
{
send_to_char ("Oh dear...big bug...please inform KaVir.\n\r", ch);
return;
}
obj->value[1] = (obj->value[0] / 5) + 1;
obj->value[2] = (obj->value[0] / 5) + 1;
obj->value[3] = sn;
free_string (obj->name);
sprintf (buf, "%s wand %s %s", ch->name, col, skill_table[sn].name);
obj->name = str_dup (buf);
free_string (obj->short_descr);
sprintf (buf, "%s's %s wand of %s", ch->name, col, skill_table[sn].name);
obj->short_descr = str_dup (buf);
free_string (obj->description);
sprintf (buf, "A %s wand is lying here.", col);
obj->description = str_dup (buf);
obj->wear_flags = ITEM_TAKE + ITEM_HOLD;
act ("You carve $p.", ch, obj, NULL, TO_CHAR);
act ("$n carves $p.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_engrave (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char col[10];
OBJ_DATA *obj;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("What spell do you wish to engrave, and on what?\n\r",
ch);
return;
}
if (((sn = skill_lookup (arg2)) == 69))
{
stc ("Nope you cant do that.\n\r", ch);
return;
}
if ((sn = skill_lookup (arg2)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (ch->pcdata->learned[sn] < 100)
{
send_to_char ("You are not adept at that spell.\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
if (obj->item_type != ITEM_STAFF)
{
send_to_char ("That is not a staff.\n\r", ch);
return;
}
if (obj->value[0] != 0 || obj->value[1] != 0 || obj->value[2] != 0
|| obj->value[3] != 0)
{
send_to_char ("You need an unenchanted staff.\n\r", ch);
return;
}
if (skill_table[sn].target == 0)
{
obj->value[0] = (ch->spl[0] + 1) / 4;
sprintf (col, "purple");
}
else if (skill_table[sn].target == 1)
{
obj->value[0] = (ch->spl[1] + 1) / 4;
sprintf (col, "red");
}
else if (skill_table[sn].target == 2)
{
obj->value[0] = (ch->spl[2] + 1) / 4;
sprintf (col, "blue");
}
else if (skill_table[sn].target == 3)
{
obj->value[0] = (ch->spl[3] + 1) / 4;
sprintf (col, "green");
}
else if (skill_table[sn].target == 4)
{
obj->value[0] = (ch->spl[4] + 1) / 4;
sprintf (col, "yellow");
}
else
{
send_to_char ("Oh dear...big bug...please inform KaVir.\n\r", ch);
return;
}
obj->value[1] = (obj->value[0] / 10) + 1;
obj->value[2] = (obj->value[0] / 10) + 1;
obj->value[3] = sn;
free_string (obj->name);
sprintf (buf, "%s staff %s %s", ch->name, col, skill_table[sn].name);
obj->name = str_dup (buf);
free_string (obj->short_descr);
sprintf (buf, "%s's %s staff of %s", ch->name, col, skill_table[sn].name);
obj->short_descr = str_dup (buf);
free_string (obj->description);
sprintf (buf, "A %s staff is lying here.", col);
obj->description = str_dup (buf);
obj->wear_flags = ITEM_TAKE + ITEM_HOLD;
act ("You engrave $p.", ch, obj, NULL, TO_CHAR);
act ("$n engraves $p.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_bake (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char col[10];
OBJ_DATA *obj;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("What spell do you wish to bake, and on what?\n\r", ch);
return;
}
if (((sn = skill_lookup (arg2)) == 69))
{
stc ("Nope you cant do that.\n\r", ch);
return;
}
if ((sn = skill_lookup (arg2)) < 0
|| (!IS_NPC (ch) && ch->level < skill_table[sn].skill_level))
{
send_to_char ("You can't do that.\n\r", ch);
return;
}
if (ch->pcdata->learned[sn] < 100)
{
send_to_char ("You are not adept at that spell.\n\r", ch);
return;
}
if ((obj = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that.\n\r", ch);
return;
}
if (obj->item_type != ITEM_PILL)
{
send_to_char ("That is not a pill.\n\r", ch);
return;
}
if (obj->value[0] != 0 || obj->value[1] != 0 || obj->value[2] != 0
|| obj->value[3] != 0)
{
send_to_char ("You need an unused pill.\n\r", ch);
return;
}
if (skill_table[sn].target == 0)
{
obj->value[0] = ch->spl[0] / 4;
sprintf (col, "purple");
}
else if (skill_table[sn].target == 1)
{
obj->value[0] = ch->spl[1] / 4;
sprintf (col, "red");
}
else if (skill_table[sn].target == 2)
{
obj->value[0] = ch->spl[2] / 4;
sprintf (col, "blue");
}
else if (skill_table[sn].target == 3)
{
obj->value[0] = ch->spl[3] / 4;
sprintf (col, "green");
}
else if (skill_table[sn].target == 4)
{
obj->value[0] = ch->spl[4] / 4;
sprintf (col, "yellow");
}
else
{
send_to_char ("Oh dear...big bug...please inform KaVir.\n\r", ch);
return;
}
obj->value[1] = sn;
if (obj->value[0] >= 25)
obj->value[2] = sn;
else
obj->value[2] = -1;
if (obj->value[0] >= 50)
obj->value[3] = sn;
else
obj->value[3] = -1;
free_string (obj->name);
sprintf (buf, "%s pill %s %s", ch->name, col, skill_table[sn].name);
obj->name = str_dup (buf);
free_string (obj->short_descr);
sprintf (buf, "%s's %s pill of %s", ch->name, col, skill_table[sn].name);
obj->short_descr = str_dup (buf);
free_string (obj->description);
sprintf (buf, "A %s pill is lying here.", col);
obj->description = str_dup (buf);
act ("You bake $p.", ch, obj, NULL, TO_CHAR);
act ("$n bakes $p.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_mount (int sn, int level, CHAR_DATA * ch, void *vo)
{
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
if (IS_NPC (ch))
return;
// stc("This spell temp disabled\n\r", ch);
// return;
if (ch->pcdata->followers > 4)
{
send_to_char ("Nothing happens.\n\r", ch);
return;
}
ch->pcdata->followers++;
if (IS_CLASS (ch, CLASS_DEMON))
{
victim = create_mobile (get_mob_index (30000));
victim->level = level * 2;
victim->armor = 0 - (10 * level);
victim->hitroll = level * 2;
victim->damroll = level * 2;
victim->hit = 250 * level;
victim->max_hit = 250 * level;
free_string (victim->lord);
victim->lord = str_dup (ch->name);
SET_BIT (victim->act, ACT_NOEXP);
SET_BIT (victim->act, ACT_MOUNT);
char_to_room (victim, ch->in_room);
act ("$N fades into existance.", ch, NULL, victim, TO_CHAR);
act ("$N fades into existance.", ch, NULL, victim, TO_ROOM);
return;
}
else if (IS_CLASS (ch, CLASS_DROW))
{
victim = create_mobile (get_mob_index (29702));
victim->level = level * 2;
victim->armor = 0 - (10 * level);
victim->hitroll = level * 2;
victim->damroll = level * 2;
victim->hit = 250 * level;
victim->max_hit = 250 * level;
free_string (victim->lord);
victim->lord = str_dup (ch->name);
SET_BIT (victim->act, ACT_NOEXP);
SET_BIT (victim->act, ACT_MOUNT);
char_to_room (victim, ch->in_room);
act ("$N fades into existance.", ch, NULL, victim, TO_CHAR);
act ("$N fades into existance.", ch, NULL, victim, TO_ROOM);
return;
}
victim = create_mobile (get_mob_index (MOB_VNUM_MOUNT));
victim->level = level;
victim->armor = 0 - (2 * level);
victim->hitroll = level;
victim->damroll = level;
victim->hit = 100 * level;
victim->max_hit = 100 * level;
free_string (victim->lord);
victim->lord = str_dup (ch->name);
SET_BIT (victim->affected_by, AFF_FLYING);
if (IS_GOOD (ch))
{
free_string (victim->name);
victim->name = str_dup ("mount white horse pegasus");
sprintf (buf, "%s's white pegasus", ch->name);
free_string (victim->short_descr);
victim->short_descr = str_dup (buf);
free_string (victim->long_descr);
victim->long_descr =
str_dup ("A beautiful white pegasus stands here.\n\r");
}
else if (IS_NEUTRAL (ch))
{
free_string (victim->name);
victim->name = str_dup ("mount griffin");
sprintf (buf, "%s's griffin", ch->name);
free_string (victim->short_descr);
victim->short_descr = str_dup (buf);
free_string (victim->long_descr);
victim->long_descr =
str_dup ("A vicious looking griffin stands here.\n\r");
}
else
{
free_string (victim->name);
victim->name = str_dup ("mount black horse nightmare");
sprintf (buf, "%s's black nightmare", ch->name);
free_string (victim->short_descr);
victim->short_descr = str_dup (buf);
free_string (victim->long_descr);
victim->long_descr =
str_dup ("A large black demonic horse stands here.\n\r");
}
char_to_room (victim, ch->in_room);
act ("$N fades into existance.", ch, NULL, victim, TO_CHAR);
act ("$N fades into existance.", ch, NULL, victim, TO_ROOM);
return;
}
/*
* Old march mount spell
void spell_mount( int sn, int level, CHAR_DATA *ch, void *vo )
{
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
if (IS_NPC(ch)) return;
victim=create_mobile( get_mob_index( MOB_VNUM_MOUNT ) );
victim->level = level;
victim->armor = 0 - (2*(level+1));
victim->hitroll = level;
victim->damroll = level;
victim->hit = 100*level;
victim->max_hit = 100*level;
SET_BIT(victim->affected_by,AFF_FLYING);
if (
if (IS_GOOD(ch))
{
free_string(victim->name);
victim->name = str_dup("mount white horse pegasus");
sprintf(buf,"%s's white pegasus",ch->name);
free_string(victim->short_descr);
victim->short_descr = str_dup(buf);
free_string(victim->long_descr);
victim->long_descr = str_dup("A beautiful white pegasus stands here.\n\r");
}
else if (IS_NEUTRAL(ch))
{
free_string(victim->name);
victim->name = str_dup("mount griffin");
sprintf(buf,"%s's griffin",ch->name);
free_string(victim->short_descr);
victim->short_descr = str_dup(buf);
free_string(victim->long_descr);
victim->long_descr = str_dup("A vicious looking griffin stands here.\n\r");
}
else
{
free_string(victim->name);
victim->name = str_dup("mount black horse nightmare");
sprintf(buf,"%s's black nightmare",ch->name);
free_string(victim->short_descr);
victim->short_descr = str_dup(buf);
free_string(victim->long_descr);
victim->long_descr = str_dup("A large black demonic horse stands here.\n\r");
}
act( "$N fades into existance.", ch, NULL, victim, TO_CHAR );
act( "$N fades into existance.", ch, NULL, victim, TO_ROOM );
char_to_room( victim, ch->in_room );
return;
}
*/
void spell_scan (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
bool found = FALSE;
for (obj = ch->carrying; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
if (obj->condition < 100 && can_see_obj (ch, obj))
{
found = TRUE;
act ("$p needs repairing.", ch, obj, NULL, TO_CHAR);
}
}
if (!found)
{
send_to_char ("None of your equipment needs repairing.\n\r", ch);
return;
}
return;
}
void spell_repair (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
bool found = FALSE;
for (obj = ch->carrying; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
if (obj->condition < 100 && can_see_obj (ch, obj))
{
found = TRUE;
obj->condition = 100;
act ("$p magically repairs itself.", ch, obj, NULL, TO_CHAR);
act ("$p magically repairs itself.", ch, obj, NULL, TO_ROOM);
}
}
if (!found)
{
send_to_char ("None of your equipment needs repairing.\n\r", ch);
return;
}
return;
}
void spell_spellproof (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if (obj->chobj != NULL)
{
send_to_char ("Your spell has no affect.\n\r", ch);
return;
}
if (IS_SET (obj->quest, QUEST_SPELLPROOF))
{
send_to_char ("That item is already resistance to spells.\n\r", ch);
return;
}
SET_BIT (obj->quest, QUEST_SPELLPROOF);
act ("$p shimmers for a moment.", ch, obj, NULL, TO_CHAR);
act ("$p shimmers for a moment.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_preserve (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if (IS_SET (obj->quest, QUEST_CLONED))
{
stc ("That item does not require preserving\n\r", ch);
return;
}
if (obj->timer < 1)
{
send_to_char ("That item doesn't require preserving.\n\r", ch);
return;
}
if (obj->chobj != NULL)
{
send_to_char ("You cannot preserve that.\n\r", ch);
return;
}
obj->timer = -1;
act ("$p shimmers for a moment.", ch, obj, NULL, TO_CHAR);
act ("$p shimmers for a moment.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_major_creation (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
char itemkind[10];
int itemtype;
int itempower = 0;
int vn = 0;
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0')
{
send_to_char
("Item can be one of: Rune, Glyph, Sigil, Book, Page or Pen.\n\r",
ch);
return;
}
/*
The Rune is the foundation/source of the spell.
The Glyphs form the focus/purpose of the spell.
The Sigils form the affects of the spell.
*/
if (!str_cmp (arg1, "rune"))
{
if (arg2[0] == '\0')
{
send_to_char ("Magical Runes consist of:\n\r\n\r", ch);
send_to_char ("FIRE WATER\n\r", ch);
send_to_char ("EARTH AIR\n\r", ch);
send_to_char ("DARK LIGHT\n\r", ch);
send_to_char ("LIFE DEATH\n\r", ch);
send_to_char ("MIND SPIRIT\n\r", ch);
send_to_char (" MASTERY\n\r\n\r", ch);
return;
}
itemtype = ITEM_SYMBOL;
vn = 1;
sprintf (itemkind, "rune");
if (!str_cmp (arg2, "fire"))
itempower = 1;
else if (!str_cmp (arg2, "air"))
itempower = 2;
else if (!str_cmp (arg2, "earth"))
itempower = 4;
else if (!str_cmp (arg2, "water"))
itempower = 8;
else if (!str_cmp (arg2, "dark"))
itempower = 16;
else if (!str_cmp (arg2, "light"))
itempower = 32;
else if (!str_cmp (arg2, "life"))
itempower = 64;
else if (!str_cmp (arg2, "death"))
itempower = 128;
else if (!str_cmp (arg2, "mind"))
itempower = 256;
else if (!str_cmp (arg2, "spirit"))
itempower = 512;
else if (!str_cmp (arg2, "mastery"))
itempower = 1024;
else
{
send_to_char ("You know of no such Rune.\n\r", ch);
return;
}
if (!IS_SET (ch->pcdata->powers[vn], itempower))
{
send_to_char ("You know of no such Rune.\n\r", ch);
return;
}
}
else if (!str_cmp (arg1, "glyph"))
{
if (arg2[0] == '\0')
{
send_to_char ("Magical Glyphs consist of:\n\r\n\r", ch);
send_to_char ("CREATION DESTRUCTION\n\r", ch);
send_to_char ("SUMMONING TRANPORTATION\n\r", ch);
send_to_char ("INFORMATION TRANSFORMATION\n\r", ch);
send_to_char ("ENHANCEMENT REDUCTION\n\r", ch);
send_to_char ("PROTECTION CONTROL\n\r\n\r", ch);
return;
}
itemtype = ITEM_SYMBOL;
vn = 2;
sprintf (itemkind, "glyph");
if (!str_cmp (arg2, "creation"))
itempower = 1;
else if (!str_cmp (arg2, "destruction"))
itempower = 2;
else if (!str_cmp (arg2, "summoning"))
itempower = 4;
else if (!str_cmp (arg2, "transformation"))
itempower = 8;
else if (!str_cmp (arg2, "transportation"))
itempower = 16;
else if (!str_cmp (arg2, "enhancement"))
itempower = 32;
else if (!str_cmp (arg2, "reduction"))
itempower = 64;
else if (!str_cmp (arg2, "control"))
itempower = 128;
else if (!str_cmp (arg2, "protection"))
itempower = 256;
else if (!str_cmp (arg2, "information"))
itempower = 512;
else
{
send_to_char ("You know of no such Glyph.\n\r", ch);
return;
}
if (!IS_SET (ch->pcdata->powers[vn], itempower))
{
send_to_char ("You know of no such Glyph.\n\r", ch);
return;
}
}
else if (!str_cmp (arg1, "sigil"))
{
if (arg2[0] == '\0')
{
send_to_char ("Magical Sigils consist of:\n\r\n\r", ch);
send_to_char ("TARGETING\n\r", ch);
send_to_char ("SELF\n\r", ch);
send_to_char ("AREA\n\r", ch);
send_to_char ("OBJECT\n\r\n\r", ch);
return;
}
itemtype = ITEM_SYMBOL;
vn = 3;
sprintf (itemkind, "sigil");
if (!str_cmp (arg2, "self"))
itempower = 1;
else if (!str_cmp (arg2, "targeting"))
itempower = 2;
else if (!str_cmp (arg2, "area"))
itempower = 4;
else if (!str_cmp (arg2, "object"))
itempower = 8;
else
{
send_to_char ("You know of no such Sigil.\n\r", ch);
return;
}
if (!IS_SET (ch->pcdata->powers[vn], itempower))
{
send_to_char ("You know of no such Sigil.\n\r", ch);
return;
}
}
else if (!str_cmp (arg1, "book"))
{
itemtype = ITEM_BOOK;
sprintf (itemkind, "book");
}
else if (!str_cmp (arg1, "page"))
{
itemtype = ITEM_PAGE;
sprintf (itemkind, "page");
}
else if (!str_cmp (arg1, "pen"))
{
itemtype = ITEM_TOOL;
sprintf (itemkind, "pen");
}
else
{
send_to_char
("Item can be one of: Rune, Glyph, Sigil, Book, Page or Pen.\n\r",
ch);
return;
}
obj = create_object (get_obj_index (OBJ_VNUM_PROTOPLASM), 0);
obj->item_type = itemtype;
if (itemtype == ITEM_SYMBOL)
{
sprintf (buf, "%s %s", itemkind, arg2);
obj->value[vn] = itempower;
}
else
sprintf (buf, "%s", itemkind);
if (itemtype == ITEM_TOOL)
{
obj->value[0] = TOOL_PEN;
obj->weight = 1;
obj->wear_flags = ITEM_TAKE + ITEM_HOLD;
}
else if (itemtype == ITEM_BOOK)
{
obj->weight = 50;
obj->wear_flags = ITEM_TAKE + ITEM_HOLD;
}
free_string (obj->name);
obj->name = str_dup (buf);
if (itemtype == ITEM_SYMBOL)
sprintf (buf, "a %s of %s", itemkind, arg2);
else
sprintf (buf, "a %s", itemkind);
free_string (obj->short_descr);
obj->short_descr = str_dup (buf);
sprintf (buf, "A %s lies here.", itemkind);
free_string (obj->description);
obj->description = str_dup (buf);
if (obj->questmaker != NULL)
free_string (obj->questmaker);
obj->questmaker = str_dup (ch->name);
obj_to_char (obj, ch);
act ("$p suddenly appears in your hands.", ch, obj, NULL, TO_CHAR);
act ("$p suddenly appears in $n's hands.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_copy (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *rune;
OBJ_DATA *page;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (IS_NPC (ch))
return;
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("Syntax is: cast 'copy' <rune> <page>.\n\r", ch);
return;
}
if ((rune = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that rune.\n\r", ch);
return;
}
if (rune->item_type != ITEM_SYMBOL)
{
send_to_char ("That item isn't a rune.\n\r", ch);
return;
}
if ((page = get_obj_carry (ch, arg2)) == NULL)
{
send_to_char ("You are not carrying that page.\n\r", ch);
return;
}
if (page->item_type != ITEM_PAGE)
{
send_to_char ("That item isn't a page.\n\r", ch);
return;
}
if (page->value[1] > 0
&& !IS_SET (ch->pcdata->powers[MPOWER_RUNE1], page->value[1]))
{
send_to_char ("You don't understand how that rune works.\n\r", ch);
return;
}
if (page->value[2] > 0
&& !IS_SET (ch->pcdata->powers[MPOWER_RUNE2], page->value[2]))
{
send_to_char ("You don't understand how that glyph works.\n\r", ch);
return;
}
if (page->value[3] > 0
&& !IS_SET (ch->pcdata->powers[MPOWER_RUNE3], page->value[3]))
{
send_to_char ("You don't understand how that sigil works.\n\r", ch);
return;
}
if (rune->value[1] == RUNE_MASTER)
{
if (IS_SET (page->quest, QUEST_MASTER_RUNE))
{
send_to_char
("There is already a master rune draw on this page.\n\r", ch);
return;
}
else if (page->value[0] + page->value[1] + page->value[2] +
page->value[3] > 0)
{
send_to_char ("There is already a spell on this page.\n\r", ch);
return;
}
else
{
act ("You copy $p rune onto $P.", ch, rune, page, TO_CHAR);
act ("$n copies $p rune onto $P.", ch, rune, page, TO_ROOM);
SET_BIT (page->quest, QUEST_MASTER_RUNE);
extract_obj (rune);
}
return;
}
else if (IS_SET (page->quest, QUEST_MASTER_RUNE))
{
send_to_char ("There is already a master rune draw on this page.\n\r",
ch);
return;
}
else if (rune->value[1] > 0 && !IS_SET (page->value[1], rune->value[1]))
page->value[1] += rune->value[1];
else if (rune->value[1] > 0)
{
send_to_char ("That rune has already been copied onto the page.\n\r",
ch);
return;
}
else if (rune->value[2] > 0 && !IS_SET (page->value[2], rune->value[2]))
page->value[2] += rune->value[2];
else if (rune->value[2] > 0)
{
send_to_char ("That glyph has already been copied onto the page.\n\r",
ch);
return;
}
else if (rune->value[3] > 0 && !IS_SET (page->value[3], rune->value[3]))
page->value[3] += rune->value[3];
else if (rune->value[3] > 0)
{
send_to_char ("That glyph has already been copied onto the page.\n\r",
ch);
return;
}
act ("You copy $p onto $P.", ch, rune, page, TO_CHAR);
act ("$n copies $p onto $P.", ch, rune, page, TO_ROOM);
extract_obj (rune);
return;
}
void oldspell_insert_page (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *page;
OBJ_DATA *book;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char ("Syntax is: cast 'insert page' <page> <book>.\n\r", ch);
return;
}
if ((page = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that page.\n\r", ch);
return;
}
if (page->item_type != ITEM_PAGE)
{
send_to_char ("That item isn't a page.\n\r", ch);
return;
}
if ((book = get_obj_carry (ch, arg2)) == NULL)
{
send_to_char ("You are not carrying that book.\n\r", ch);
return;
}
if (book->item_type != ITEM_BOOK)
{
send_to_char ("That item isn't a book.\n\r", ch);
return;
}
if (IS_SET (book->value[1], CONT_CLOSED))
{
send_to_char ("First you need to open it!\n\r", ch);
return;
}
obj_from_char (page);
obj_to_obj (page, book);
book->value[3] += 1;
book->value[2] = book->value[3];
page->value[0] = book->value[3];
page->specpower = book->value[3] + 1;
act ("You insert $p into $P.", ch, page, book, TO_CHAR);
act ("$n inserts $p into $P.", ch, page, book, TO_ROOM);
return;
}
void ospell_remove_page (int sn, int level, CHAR_DATA * ch, void *vo)
{
char arg1[MAX_INPUT_LENGTH];
OBJ_DATA *page;
OBJ_DATA *book;
OBJ_DATA *page_next;
int count = 0;
target_name = one_argument (target_name, arg1);
if (arg1[0] == '\0')
{
send_to_char ("Syntax is: cast 'remove page' <book>.\n\r", ch);
return;
}
if ((book = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that book.\n\r", ch);
return;
}
if (book->item_type != ITEM_BOOK)
{
send_to_char ("That item isn't a book.\n\r", ch);
return;
}
if (IS_SET (book->value[1], CONT_CLOSED))
{
send_to_char ("First you need to open it!\n\r", ch);
return;
}
if (book->value[2] == 0)
{
send_to_char ("You cannot remove the index page!\n\r", ch);
return;
}
if ((page = get_page (book, book->value[2])) == NULL)
{
send_to_char ("The page seems to have been torn out.\n\r", ch);
return;
}
obj_from_obj (page);
obj_to_char (page, ch);
page->value[0] = 0;
act ("You remove $p from $P.", ch, page, book, TO_CHAR);
act ("$n removes $p from $P.", ch, page, book, TO_ROOM);
for (page = book->contains; page != NULL; page = page_next)
{
page_next = page->next_content;
count += 1;
page->value[0] = count;
}
book->value[3] = count;
if (book->value[2] > book->value[3])
book->value[2] = book->value[3];
return;
}
void spell_insert_page (int sn, int level, CHAR_DATA * ch, void *vo)
{ // Repaired and overhauled by Serenity/Jasmine
OBJ_DATA *page; // page to insert
OBJ_DATA *book_page; // pages already in the book
OBJ_DATA *book_page_next; // next argument for above
OBJ_DATA *book; // the book we are changing
char arg1[MAX_INPUT_LENGTH]; // which page in inventory
char arg2[MAX_INPUT_LENGTH]; // which book
char arg3[MAX_INPUT_LENGTH]; // Insert page after which page
int iarg3 = 0; // Integer argument for above
target_name = one_argument (target_name, arg1);
target_name = one_argument (target_name, arg2);
target_name = one_argument (target_name, arg3);
if (arg1[0] == '\0' || arg2[0] == '\0')
{
send_to_char
("Syntax is: cast 'insert page' <page> <book> [page to insert after].\n\r",
ch);
return;
}
if ((arg3[0] != '\0') && (!is_number (arg3)))
{
send_to_char
("If you are going to specify a location, make SENSE!\n\r", ch);
return;
}
iarg3 = atoi (arg3);
if ((page = get_obj_carry (ch, arg1)) == NULL)
{
send_to_char ("You are not carrying that page.\n\r", ch);
return;
}
if (page->item_type != ITEM_PAGE)
{
send_to_char ("That item isn't a page.\n\r", ch);
return;
}
if ((book = get_obj_carry (ch, arg2)) == NULL)
{
send_to_char ("You are not carrying that book.\n\r", ch);
return;
}
if (book->item_type != ITEM_BOOK)
{
send_to_char ("That item isn't a book.\n\r", ch);
return;
}
if (IS_SET (book->value[1], CONT_CLOSED))
{
send_to_char ("First you need to open it!\n\r", ch);
return;
}
if (iarg3 < 0)
{
send_to_char
("If you want the page in FRONT of the book cover, just keep ahold of it then ya silly git.\n\r",
ch);
return;
}
if (iarg3 >= book->value[3]) // if it equals it it will crash to
iarg3 = 0; // reset it to 0
if (iarg3 == 0) // default method, just append to end of book
{
obj_from_char (page);
obj_to_obj (page, book);
book->value[3] += 1;
book->value[2] = book->value[3];
page->value[0] = book->value[3];
page->specpower = book->value[3] + 1;
}
else // Lets put it INTO the book not at the end
{
int page_count = 0; // pages in the book
int cur_page = 1;
page->value[0] = iarg3 + 1; // We are adding it AFTER the specified page
obj_from_char (page);
page->in_obj = book; // Manually duplicating the obj_to_obj funct on purpose
page->in_room = NULL;
page->carried_by = NULL;
// 6 5 4 3 2 1 insert a after page 3 (book is really 1 2 3 4 5 6 order)
// 6 5 4 a 3 2 1 so book will really be 1 2 3 a 4 5 6 order
for (book_page = book->contains; book_page != NULL;
book_page = book_page_next)
{
book_page_next = book_page->next_content;
if (book_page_next->value[0] == iarg3) // we have found our page we are adding after
{
page->next_content = book_page_next; // Ok the next page in the series should be the one
// that was originally after the page we are inserting after
book_page->next_content = page; // We now insert the new page after the current one.
// and we should now be done with the loop.
break;
}
else
{
continue; // Wrong page, continue loop
}
}
for (book_page = book->contains; book_page != NULL;
book_page = book_page_next)
{
book_page_next = book_page->next_content;
page_count++;
}
book->value[3] = page_count; // Should be the original number + 1;
// We do not change the current page of the book we are on.
// We WILL need to renumber all the specpowers to match, as
// Well as all the page numbers.
// Now we renumber the book....since the loop seems to go through the book BACKWARDS we'll make the assumption
// that we are going backwards too here.
cur_page = page_count;
for (book_page = book->contains; book_page != NULL;
book_page = book_page_next)
{
book_page_next = book_page->next_content;
book_page->value[0] = cur_page;
book_page->specpower = cur_page + 1;
cur_page--;
}
}
act ("You insert $p into $P.", ch, page, book, TO_CHAR);
act ("$n inserts $p into $P.", ch, page, book, TO_ROOM);
return;
}
void spell_remove_page (int sn, int level, CHAR_DATA * ch, void *vo)
{ // Repaired and overhauled by Serenity/Jasmine
char arg1[5000]; // Making this Smaller
char arg2[5000]; // This too is new
int iarg1 = 0; // Integer version of argument 1
OBJ_DATA *page;
OBJ_DATA *save_page=NULL; // Page being removed
OBJ_DATA *book;
OBJ_DATA *page_next;
// int count = 0;
int page_count = 0;
int cur_page = 1;
target_name = one_argument (target_name, arg1); // Assign page number to first argument
one_argument (target_name, arg2); // Assign book to second argument
if (arg1[0] == '\0')
{
send_to_char ("Syntax is: cast 'remove page' <page number> <book>.\n\r",
ch);
return;
}
if (arg2[0] == '\0')
{
send_to_char ("Syntax is: cast 'remove page' <page number> <book>.\n\r",
ch);
return;
}
if (!is_number (arg1))
{
send_to_char ("Syntax is: cast 'remove page' <page number> <book>.\n\r",
ch);
return;
}
iarg1 = atoi (arg1);
if ((book = get_obj_carry (ch, arg2)) == NULL)
{
send_to_char ("You are not carrying that book.\n\r", ch);
return;
}
if (book->item_type != ITEM_BOOK)
{
send_to_char ("That item isn't a book.\n\r", ch);
return;
}
if (IS_SET (book->value[1], CONT_CLOSED))
{
send_to_char ("First you need to open it!\n\r", ch);
return;
}
if ((iarg1 < 1) || (iarg1 > book->value[3]))
{
send_to_char
("Please use a rational argument.\n\rValues less then 1 are pointless, and so are values more then pages in the book.\n\r",
ch);
return;
}
/*
if ( book->value[2] == 0 )
{
send_to_char("You cannot remove the index page!\n\r",ch);
return;
}
*/
/*
if ( ( page = get_page(book, book->value[2]) ) == NULL )
{
send_to_char("The page seems to have been torn out.\n\r",ch);
return;
}
*/
// let's try this... instead of removing the page first, let's remove the page last...
// instead let's change it so that in the array, we just skip over the page and move it to the end
if ((page = get_page (book, iarg1)) == NULL) // Make sure the page exists first
{
send_to_char ("This page appears to be missing...\n\r", ch);
return;
}
for (page = book->contains; page != NULL; page = page_next)
{
page_count++; // How many pages in this book.
page_next = page->next_content;
if (page->value[0] == iarg1) // This is the page we are looking for
save_page = page;
else // This is not the page you are looking for, *waves hand*... -- Jedi:Jasmine
continue;
}
obj_from_obj (save_page);
obj_to_char (save_page, ch);
save_page->value[0] = 0;
cur_page = 1;
// ok now let's re-order the pages
for (page = book->contains; page != NULL; page = page_next)
{
page_next = page->next_content;
page->value[0] = page_count - cur_page;
page->specpower = (page_count - cur_page) + 1;
cur_page++;
}
act ("You remove $p from $P.", ch, save_page, book, TO_CHAR);
act ("$n removes $p from $P.", ch, save_page, book, TO_ROOM);
/* for ( page = book->contains; page != NULL; page = page_next )
{
page_count++;
page_next = page->next_content;
count += 1;
page->value[0] = count;
}
*/
book->value[3] = page_count - 1; // Don't make it count, reset the books max pages proper amount -Jasmine
book->value[2] = 0; // Reset current page to index. -Jasmine
return;
}
void enhance_stat (int sn, int level, CHAR_DATA * ch, CHAR_DATA * victim,
int apply_bit, int bonuses, int affect_bit)
{
AFFECT_DATA af;
if (IS_ITEMAFF (victim, ITEMA_REFLECT))
{
send_to_char ("You are unable to focus your spell.\n\r", ch);
return;
}
if (IS_SET (affect_bit, AFF_SHADOWPLANE) && victim->fight_timer > 0)
{
stc ("Not with a fight timer!\n\r", ch);
return;
}
if (IS_SET (affect_bit, AFF_ETHEREAL) && victim->fight_timer > 0)
{
stc ("Not with a fight timer!\n\r", ch);
return;
}
if (IS_SET(affect_bit, AFF_TOTALBLIND))
affect_bit -= AFF_TOTALBLIND;
if (IS_SET(affect_bit, AFF_DROWFIRE))
affect_bit -= AFF_DROWFIRE;
if (IS_SET(affect_bit, AFF_ENTRAILS))
affect_bit -= AFF_ENTRAILS;
if (IS_SET(affect_bit, AFF_INFIRMITY))
affect_bit -= AFF_INFIRMITY;
if (IS_SET(affect_bit, AFF_ETHEREAL) && victim->position == POS_FIGHTING)
affect_bit -= AFF_ETHEREAL;
if (IS_SET(affect_bit, AFF_SHADOWPLANE) && victim->position == POS_FIGHTING)
affect_bit -= AFF_SHADOWPLANE;
if (IS_SET(affect_bit, AFF_POISON) && IS_CLASS(victim, CLASS_VAMPIRE))
affect_bit -= AFF_POISON;
if (IS_SET(affect_bit, AFF_SLEEP) && IS_IMMUNE(victim, IMM_SLEEP))
affect_bit -= AFF_SLEEP;
if (IS_SET(affect_bit, AFF_FLAMING) && IS_IMMUNE(victim, IMM_HEAT))
affect_bit -= AFF_FLAMING;
else if (IS_SET(affect_bit, AFF_FLAMING) && WORN_ARTIFACT (victim, ARTI_DEMONS_HEART))
affect_bit -= AFF_FLAMING;
if (IS_SET (affect_bit, AFF_WEBBED) && IS_AFFECTED (victim, AFF_WEBBED))
affect_bit -= AFF_WEBBED;
else if (IS_SET (affect_bit, AFF_WEBBED) && is_safe (ch, victim))
affect_bit -= AFF_WEBBED;
if (IS_SET(affect_bit, AFF_SANCTUARY) && WORN_ARTIFACT(victim, ARTI_CLOAK_OF_THE_ARCHMAGI))
affect_bit -= AFF_SANCTUARY;
if (IS_SET(affect_bit, AFF_PROTECT) && WORN_ARTIFACT(victim, ARTI_HEART_OF_DARKNESS))
affect_bit -= AFF_PROTECT;
if (IS_SET(affect_bit, AFF_HIDE) && IS_CLASS (victim, CLASS_NINJA))
affect_bit -= AFF_HIDE;
if (IS_SET (affect_bit, AFF_CHARM) && !IS_AFFECTED (victim, AFF_CHARM))
{
if (victim->level <= 50
&& (IS_NPC (victim) || !IS_IMMUNE (victim, IMM_CHARM)))
{
if (victim->master)
stop_follower (victim);
add_follower (victim, ch);
}
else
{
send_to_char ("The spell failed.\n\r", ch);
return;
}
}
af.type = sn;
af.duration = level;
af.location = apply_bit;
af.modifier = bonuses;
af.bitvector = affect_bit;
affect_to_char (victim, &af);
return;
}
void spell_chaos_blast (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice (level, 80);
if (saves_spell (level, victim))
dam *= 0.5;
if (IS_AFFECTED (ch, AFF_SANCTUARY))
dam *= 0.5;
if (IS_ITEMAFF (ch, ITEMA_CHAOSSHIELD))
dam *= 0.65;
if (!IS_NPC (ch))
dam *= 0.5;
if (IS_NPC (victim) && dam >= victim->hit)
dam = victim->hit - 1;
if (dam == 0)
return;
dam *= 0.60;
damage (ch, victim, dam, sn);
return;
/*
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (IS_ITEMAFF(victim, ITEMA_CHAOSSHIELD))
return;
dam = dice(level, 6);
if (saves_spell(level, victim))
dam *= 0.5;
damage(ch, victim, dam, sn);
return;
*/
}
void spell_resistance (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if (obj->chobj != NULL)
{
send_to_char ("Your spell has no affect.\n\r", ch);
return;
}
if (IS_SET (obj->quest, QUEST_ARTIFACT))
{
send_to_char ("Not on artifacts.\n\r", ch);
return;
}
if (obj->resistance <= 10)
{
send_to_char ("You cannot make that item any more resistant.\n\r", ch);
return;
}
obj->resistance = 10;
act ("$p sparkles for a moment.", ch, obj, NULL, TO_CHAR);
act ("$p sparkles for a moment.", ch, obj, NULL, TO_ROOM);
return;
}
void spell_drowfire (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af1;
AFFECT_DATA af2;
AFFECT_DATA af3;
act ("You chant some arcane words on $N.", ch, NULL, victim, TO_CHAR);
act ("$n chants some arcane words on $N.", ch, NULL, victim, TO_NOTVICT);
act ("$n chants some arcane words on you.", ch, NULL, victim, TO_VICT);
if (IS_AFFECTED (victim, AFF_DROWFIRE))
{
send_to_char ("They are already affected by drowfire.\n\r", ch);
return;
}
if (is_safe (ch, victim))
return;
if (saves_spell (level, victim))
return;
af1.type = sn;
af1.location = APPLY_AC;
af1.modifier = 500;
af1.duration = 2;
af1.bitvector = AFF_DROWFIRE;
affect_to_char (victim, &af1);
af2.type = sn;
af2.location = APPLY_STR;
af2.modifier = -10;
af2.duration = 2;
af2.bitvector = AFF_CURSE;
affect_to_char (victim, &af2);
af3.type = sn;
af3.location = APPLY_HITROLL;
af3.modifier = -100;
af3.duration = 2;
af3.bitvector = AFF_BLIND;
affect_to_char (victim, &af3);
send_to_char ("You are engulfed in drowfire!\n\r", victim);
act ("$n is engulfed in drowfire!", victim, NULL, NULL, TO_ROOM);
return;
}
void spell_darkness (int sn, int level, CHAR_DATA * ch, void *vo)
{
AFFECT_DATA af;
if (IS_AFFECTED (ch, AFF_DARKNESS))
{
send_to_char ("You are already surrounded in darkness.\n\r", ch);
return;
}
af.type = sn;
af.duration = 10;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DARKNESS;
affect_to_char (ch, &af);
send_to_char ("You are surrounded in a globe of darkness.\n\r", ch);
SET_BIT (ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
return;
}
void spell_web (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
act ("You point your finger at $N and a web flies from your hand!", ch,
NULL, victim, TO_CHAR);
act ("$n points $s finger at $N and a web flies from $s hand!", ch, NULL,
victim, TO_NOTVICT);
act ("$n points $s finger at you and a web flies from $s hand!", ch, NULL,
victim, TO_VICT);
if (IS_AFFECTED (victim, AFF_WEBBED))
{
send_to_char ("But they are already webbed!\n\r", ch);
return;
}
if (victim->in_room->vnum == ROOM_VNUM_ALTAR)
return;
if (is_safe (ch, victim))
return;
if (saves_spell (level, victim) && victim->position >= POS_FIGHTING)
{
send_to_char ("You dodge the web!\n\r", victim);
act ("$n dodges the web!", victim, NULL, NULL, TO_ROOM);
return;
}
af.type = sn;
af.location = APPLY_AC;
af.modifier = 200;
af.duration = number_range (2, 4);
af.bitvector = AFF_WEBBED;
affect_to_char (victim, &af);
send_to_char ("You are coated in a sticky web!\n\r", victim);
act ("$n is coated in a sticky web!", victim, NULL, NULL, TO_ROOM);
return;
}
/*
void spell_godbless( int sn, int level, CHAR_DATA *ch, void *vo)
{
AFFECT_DATA af1;
AFFECT_DATA af2;
AFFECT_DATA af3;
AFFECT_DATA af4;
AFFECT_DATA af5;
act("You kneel on your knees and pray to god.",ch,NULL,NULL,TO_CHAR);
act("$n kneels on his knees and prays to god.",ch,NULL,NULL,TO_NOTVICT);
if (IS_AFFECTED(ch, AFF_GODBLESS))
{
send_to_char("You are already blessed by god.\n\r",ch);
return;
}
af1.type = sn;
af1.location = APPLY_AC;
af1.modifier = -400;
af1.duration = 1000;
af1.bitvector = 0;
affect_to_char(ch, &af1);
af2.type = sn;
af2.location = APPLY_STR;
af2.modifier = +7;
af2.duration = 1000;
af2.bitvector = 0;
affect_to_char(ch, &af2);
af3.type = sn;
af3.location = APPLY_HITROLL;
af3.modifier = 200;
af3.duration = 1000;
af3.bitvector = 0;
affect_to_char(ch, &af3);
af4.type = sn;
af4.location = APPLY_DAMROLL;
af4.modifier = 200;
af4.duration = 1000;
af4.bitvector = 0;
affect_to_char(ch, &af4);
af5.type = sn;
af5.location = APPLY_DEX;
af5.modifier = +7;
af5.duration = 1000;
af5.bitvector = 0;
affect_to_char(ch, &af5);
send_to_char("You are blessed by God!\n\r", ch);
act("$n blessed by God!",ch,NULL,NULL,TO_ROOM);
SET_BIT( ch->affected_by, AFF_GODBLESS );
return;
}
*/
void spell_llothbless (int sn, int level, CHAR_DATA * ch, void *vo)
{
AFFECT_DATA af1;
AFFECT_DATA af2;
AFFECT_DATA af3;
AFFECT_DATA af4;
AFFECT_DATA af5;
act ("You kneel on your knees and pray to Lloth.", ch, NULL, NULL,
TO_CHAR);
act ("$n kneels on his knees and prays to Lloth.", ch, NULL, NULL,
TO_NOTVICT);
/*
if (IS_AFFECTED(ch, AFF_LLOTHBLESS))
{
send_to_char("You are already blessed by Lloth.\n\r",ch);
return;
}
*/
af1.type = sn;
af1.location = APPLY_AC;
af1.modifier = -300;
af1.duration = 1000;
af1.bitvector = 0;
affect_to_char (ch, &af1);
af2.type = sn;
af2.location = APPLY_STR;
af2.modifier = +10;
af2.duration = 1000;
af2.bitvector = 0;
affect_to_char (ch, &af2);
af3.type = sn;
af3.location = APPLY_HITROLL;
af3.modifier = 200;
af3.duration = 1000;
af3.bitvector = 0;
affect_to_char (ch, &af3);
af4.type = sn;
af4.location = APPLY_DAMROLL;
af4.modifier = 200;
af4.duration = 1000;
af4.bitvector = 0;
affect_to_char (ch, &af4);
af5.type = sn;
af5.location = APPLY_DEX;
af5.modifier = +10;
af5.duration = 1000;
af5.bitvector = 0;
affect_to_char (ch, &af5);
send_to_char ("You are blessed by Lloth!\n\r", ch);
act ("$n blessed by Lloth!", ch, NULL, NULL, TO_ROOM);
// SET_BIT( ch->affected_by, AFF_LLOTHBLESS );
return;
}
void spell_totalblind (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_INPUT_LENGTH];
if (IS_AFFECTED (victim, AFF_TOTALBLIND))
{
send_to_char ("But they are already blinded!\n\r", ch);
return;
}
af.type = sn;
af.location = APPLY_DEX;
af.modifier = -5;
af.duration = 1 + level;
af.bitvector = AFF_TOTALBLIND;
affect_to_char (victim, &af);
send_to_char ("A dark blaze flashes in your eyes.\n\r", victim);
if (!IS_NPC (victim))
sprintf (buf, "%s is blinded by a dark blaze of light!\n\r",
victim->name);
else
sprintf (buf, "%s is blinded by a dark blaze of light!\n\r",
victim->short_descr);
send_to_char (buf, ch);
SET_BIT (victim->affected_by, AFF_TOTALBLIND);
return;
}
void spell_polymorph (int sn, int level, CHAR_DATA * ch, void *vo)
{
AFFECT_DATA af;
char buf[MAX_INPUT_LENGTH];
if (IS_AFFECTED (ch, AFF_POLYMORPH))
{
send_to_char ("You cannot polymorph from this form.\n\r", ch);
return;
}
if (ch->position == POS_FIGHTING || is_affected (ch, sn))
return;
if (!str_cmp (target_name, "frog"))
{
if (!IS_NPC (ch) && ch->stance[0] != -1)
do_stance (ch, "");
if (ch->mounted == IS_RIDING)
do_dismount (ch, "");
act ("$n polymorphs into a frog!", ch, NULL, NULL, TO_ROOM);
send_to_char ("You polymorph into a frog!\n\r", ch);
clear_stats (ch);
af.type = sn;
af.duration = number_range (3, 5);
af.location = APPLY_POLY;
af.modifier = POLY_FROG;
af.bitvector = AFF_POLYMORPH;
affect_to_char (ch, &af);
sprintf (buf, "%s the frog", ch->name);
free_string (ch->morph);
ch->morph = str_dup (buf);
return;
}
else if (!str_cmp (target_name, "fish"))
{
if (!IS_NPC (ch) && ch->stance[0] != -1)
do_stance (ch, "");
if (ch->mounted == IS_RIDING)
do_dismount (ch, "");
act ("$n polymorphs into a fish!", ch, NULL, NULL, TO_ROOM);
send_to_char ("You polymorph into a fish!\n\r", ch);
clear_stats (ch);
af.type = sn;
af.duration = number_range (3, 5);
af.location = APPLY_POLY;
af.modifier = POLY_FISH;
af.bitvector = AFF_POLYMORPH;
affect_to_char (ch, &af);
sprintf (buf, "%s the fish", ch->name);
free_string (ch->morph);
ch->morph = str_dup (buf);
return;
}
else if (!str_cmp (target_name, "raven"))
{
if (!IS_NPC (ch) && ch->stance[0] != -1)
do_stance (ch, "");
if (ch->mounted == IS_RIDING)
do_dismount (ch, "");
act ("$n polymorphs into a raven!", ch, NULL, NULL, TO_ROOM);
send_to_char ("You polymorph into a raven!\n\r", ch);
clear_stats (ch);
af.type = sn;
af.duration = number_range (3, 5);
af.location = APPLY_AC;
af.modifier = -150;
if (IS_AFFECTED (ch, AFF_FLYING))
af.bitvector = AFF_POLYMORPH;
else
af.bitvector = AFF_POLYMORPH + AFF_FLYING;
affect_to_char (ch, &af);
af.location = APPLY_POLY;
af.modifier = POLY_RAVEN;
affect_to_char (ch, &af);
sprintf (buf, "%s the raven", ch->name);
free_string (ch->morph);
ch->morph = str_dup (buf);
return;
}
send_to_char ("You can polymorph into a frog, a fish, or an raven.\n\r",
ch);
return;
}
void spell_contraception (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF2_CONTRACEPTION))
return;
if (victim->sex != SEX_FEMALE)
return;
af.type = sn;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF2_CONTRACEPTION;
affect_to_char (victim, &af);
return;
}
void spell_find_familiar (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim;
CHAR_DATA *familiar;
if (target_name[0] == '\0')
{
send_to_char
("Your familiar can be a frog, a raven, a cat or a dog.\n\r", ch);
return;
}
if ((familiar = ch->pcdata->familiar) != NULL)
{
send_to_char ("But you already have a familiar!\n\r", ch);
return;
}
if (!str_cmp (target_name, "frog"))
{
victim = create_mobile (get_mob_index (MOB_VNUM_FROG));
if (victim == NULL)
{
send_to_char ("Error - please inform KaVir.\n\r", ch);
return;
}
}
else if (!str_cmp (target_name, "raven"))
{
victim = create_mobile (get_mob_index (MOB_VNUM_RAVEN));
if (victim == NULL)
{
send_to_char ("Error - please inform KaVir.\n\r", ch);
return;
}
}
else if (!str_cmp (target_name, "cat"))
{
victim = create_mobile (get_mob_index (MOB_VNUM_CAT));
if (victim == NULL)
{
send_to_char ("Error - please inform KaVir.\n\r", ch);
return;
}
}
else if (!str_cmp (target_name, "dog"))
{
victim = create_mobile (get_mob_index (MOB_VNUM_DOG));
if (victim == NULL)
{
send_to_char ("Error - please inform KaVir.\n\r", ch);
return;
}
}
else
{
send_to_char
("Your familiar can be a frog, a raven, a cat or a dog.\n\r", ch);
return;
}
act ("You make a few gestures and $N appears in a swirl of smoke.", ch,
NULL, victim, TO_CHAR);
act ("$n makes a few gestures and $N appears in a swirl of smoke.", ch,
NULL, victim, TO_ROOM);
char_to_room (victim, ch->in_room);
ch->pcdata->familiar = victim;
victim->wizard = ch;
return;
}
void spell_infirmity (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED (victim, AFF_INFIRMITY))
{
act ("A look of concentration passes over $n's face.", ch, NULL, NULL,
TO_ROOM);
send_to_char ("A look of concentration passes over your face.\n\r", ch);
send_to_char ("They are already weak.\n\r", ch);
return;
}
af.type = sn;
af.duration = level;
af.location = APPLY_DEX;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_WIS;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_CON;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_INT;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_DAMROLL;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
af.type = sn;
af.duration = level;
af.location = APPLY_HITROLL;
af.modifier = 0 - level;
af.bitvector = AFF_INFIRMITY;
affect_to_char (victim, &af);
send_to_char ("A look of concentration passes over your face.\n\r", ch);
act ("A look of concentration passes over $n's face.", ch, NULL, NULL,
TO_ROOM);
send_to_char ("You feel weaker.\n\r", victim);
send_to_char ("You feel slower.\n\r", victim);
send_to_char ("You feel less healthy.\n\r", victim);
act ("$n looks weaker.", victim, NULL, NULL, TO_ROOM);
act ("$n looks slower.", victim, NULL, NULL, TO_ROOM);
act ("$n looks less healthy.", victim, NULL, NULL, TO_ROOM);
return;
}
void spell_improve (int sn, int level, CHAR_DATA * ch, void *vo)
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if (IS_SET (obj->quest, QUEST_ARTIFACT))
{
send_to_char ("Not on artifacts.\n\r", ch);
return;
}
if (obj->pIndexData->vnum != OBJ_VNUM_PROTOPLASM
&& (!IS_SET (obj->spectype, SITEM_DEMONIC)
&& obj->specpower < ARM_BRASS))
{
send_to_char ("You cannot enhance this object.\n\r", ch);
return;
}
if (IS_SET (obj->quest, QUEST_IMPROVED))
{
send_to_char ("This item has already been improved.\n\r", ch);
return;
}
else if (obj->points < 750 && obj->item_type != ITEM_WEAPON)
{
send_to_char ("The object must be worth at least 750 quest points.\n\r",
ch);
return;
}
else if (obj->points < 1500 && obj->item_type == ITEM_WEAPON)
{
send_to_char
("The object must be worth at least 1500 quest points.\n\r", ch);
return;
}
REMOVE_BIT (obj->quest, QUEST_STR);
REMOVE_BIT (obj->quest, QUEST_DEX);
REMOVE_BIT (obj->quest, QUEST_INT);
REMOVE_BIT (obj->quest, QUEST_WIS);
REMOVE_BIT (obj->quest, QUEST_CON);
REMOVE_BIT (obj->quest, QUEST_HITROLL);
REMOVE_BIT (obj->quest, QUEST_DAMROLL);
REMOVE_BIT (obj->quest, QUEST_HIT);
REMOVE_BIT (obj->quest, QUEST_MANA);
REMOVE_BIT (obj->quest, QUEST_MOVE);
REMOVE_BIT (obj->quest, QUEST_AC);
SET_BIT (obj->quest, QUEST_IMPROVED);
act ("$p flickers for a moment.", ch, obj, NULL, TO_CHAR);
act ("$p flickers for a moment.", ch, obj, NULL, TO_ROOM);
return;
}
/* New MAGE spells */
void spell_read_aura (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char buf[MAX_STRING_LENGTH];
int con_hit, con_dam, con_ac, con_hp, con_mana, con_move;
int con_str, con_int, con_dex, con_wis, con_con;
int con_max_hp, con_max_mana, con_max_move;
if (IS_IMMORTAL (victim))
{
send_to_char ("Nothing happens.\n\r", ch);
return;
}
act ("You examine $N intently.", ch, NULL, victim, TO_CHAR);
act ("$n examines you intently.", ch, NULL, victim, TO_VICT);
act ("$n examines $N intently.", ch, NULL, victim, TO_NOTVICT);
sprintf (buf, "Name : %s.\n\r",
IS_NPC (victim) ? victim->short_descr : victim->name);
send_to_char (buf, ch);
sprintf (buf, "$E is %s.",
IS_NPC (victim) ? "a NPC" : IS_HERO (victim) ? "an avatar" :
IS_IMMORTAL (victim) ? "an immortal" : "a mortal");
act (buf, ch, NULL, victim, TO_CHAR);
if (!IS_NPC (victim) && IS_HERO (victim) && victim->class > 0)
{
switch (victim->class)
{
default:
sprintf (buf, " ");
break;
case CLASS_VAMPIRE:
sprintf (buf, "$E is a vampire. Clan : %s. Gen : %d.",
strlen (victim->clan) < 2 ? "Caitiff" : victim->clan,
victim->pcdata->stats[UNI_GEN]);
break;
case CLASS_WEREWOLF:
sprintf (buf, "$E is a werewolf. Tribe : %s. Gen : %d.",
strlen (victim->clan) < 2 ? "Ronin" : victim->clan,
victim->pcdata->stats[UNI_GEN]);
break;
case CLASS_MAGE:
sprintf (buf, "$E is an %s of %s.",
victim->level ==
LEVEL_APPRENTICE ? "Apprentice" : victim->level ==
LEVEL_MAGE ? "Adept" : "Oracle", victim->clan);
break;
case CLASS_DEMON:
sprintf (buf, "$E is a %s.",
IS_SET (victim->special,
SPC_DEMON_LORD) ? "demon lord" : IS_SET (victim->
special,
SPC_PRINCE)
? "demon prince" : IS_SET (victim->special,
SPC_SIRE) ? "greater demon" :
"lesser demon");
break;
}
act (buf, ch, NULL, victim, TO_CHAR);
}
sprintf (buf, "Status : %d. Alignment : %d\n\r", victim->race,
victim->alignment);
send_to_char (buf, ch);
/*
if ( !IS_NPC( victim ) && IS_EXTRA( victim, EXTRA_FAKE_CON ) )
{
con_hit = victim->pcdata->fake_hit;
con_dam = victim->pcdata->fake_dam;
con_ac = victim->pcdata->fake_ac;
con_str = victim->pcdata->fake_stats[STAT_STR];
con_int = victim->pcdata->fake_stats[STAT_INT];
con_dex = victim->pcdata->fake_stats[STAT_DEX];
con_wis = victim->pcdata->fake_stats[STAT_WIS];
con_con = victim->pcdata->fake_stats[STAT_CON];
con_hp = victim->pcdata->fake_hp;
con_mana = victim->pcdata->fake_mana;
con_move = victim->pcdata->fake_move;
con_max_hp = victim->pcdata->fake_max_hp;
con_max_mana = victim->pcdata->fake_max_mana;
con_max_move = victim->pcdata->fake_max_move;
}
else
{
*/
con_hit = char_hitroll (victim);
con_dam = char_damroll (victim);
con_ac = char_ac (victim);
con_str = get_curr_str (victim);
con_int = get_curr_int (victim);
con_dex = get_curr_dex (victim);
con_wis = get_curr_wis (victim);
con_con = get_curr_con (victim);
con_hp = victim->hit;
con_mana = victim->mana;
con_move = victim->move;
con_max_hp = victim->max_hit;
con_max_mana = victim->max_mana;
con_max_move = victim->max_move;
// }
sprintf (buf, "Hp : %d/%d. Mana : %d/%d. Move : %d/%d.\n\r", con_hp,
con_max_hp, con_mana, con_max_mana, con_move, con_max_move);
send_to_char (buf, ch);
sprintf (buf, "Str : %d. Dex : %d. Int : %d. Wis : %d. Con : %d.\n\r",
con_str, con_dex, con_int, con_wis, con_con);
send_to_char (buf, ch);
sprintf (buf, "Hit : %d. Dam : %d. Ac : %d.\n\r", con_hit, con_dam,
con_ac);
send_to_char (buf, ch);
return;
}
void spell_restore_hp (int sn, int level, CHAR_DATA * ch, void *vo)
{
if (IS_NPC (ch))
return;
if (ch->hit < ch->max_hit)
ch->hit = ch->max_hit;
return;
}
void spell_restore_mana (int sn, int level, CHAR_DATA * ch, void *vo)
{
if (IS_NPC (ch))
return;
if (ch->mana < ch->max_mana)
ch->mana = ch->max_mana;
return;
}
void spell_restore_move (int sn, int level, CHAR_DATA * ch, void *vo)
{
if (IS_NPC (ch))
return;
if (ch->move < ch->max_move)
ch->move = ch->max_move;
return;
}
void spell_solar_flare (int sn, int level, CHAR_DATA * ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char buf[MAX_INPUT_LENGTH];
int dam;
switch (victim->class)
{
default: dam = number_range(1000,3000); break;
case CLASS_DEMON:
case CLASS_DROW: dam = number_range(3000,4000); break;
case CLASS_MAGE:
case CLASS_WEREWOLF:
case CLASS_HIGHLANDER:
case CLASS_NINJA:
case CLASS_MONK:
case CLASS_DRAGON:
dam = number_range(1000,2000); break;
case CLASS_VAMPIRE: dam = (ch->beast == 0 ? number_range(1000,2000) : number_range(4000,5000)); break;
case CLASS_FAE: dam = number_range(2000,3000); break;
}
if (IS_AFFECTED(victim, AFF_PROTECT) && IS_EVIL(ch))
dam -= dam * 0.25;
if (IS_AFFECTED(victim, AFF_SANCTUARY))
dam *= 0.5;
sprintf (buf, "%s is scorched by a flare from your solar shield![#r%d#n]\n\r", IS_NPC(victim) ? victim->short_descr : victim->name, dam);
if (!IS_SET (ch->more, MORE_SHIELDS))
send_to_char (buf, ch);
sprintf (buf, "You are scorched by a flare from %s's solar shield![#r%d#n]\n\r", IS_NPC(ch) ? ch->short_descr : ch->name, dam);
if (!IS_SET (victim->more, MORE_SHIELDS))
send_to_char (buf, victim);
act ("$N looks scorched as $n's shield flares up!", ch, NULL,
victim, TO_NOTVICT);
hurt_person (ch, victim, dam);
return;
}