Gcc 9.2.1 warnings (#87)

* Make sure all followers are free'd before freeing the character list

Otherwise, the followers structs will point to free'd memory and
the stop_follower call will attempt to dereference a free'd
characters' followers list.

* fix gcc warning: truncation in strncat

In file included from /usr/include/string.h:494,
from sysdep.h:74,
from act.item.c:12:
In function ‘strncat’,
inlined from ‘name_from_drinkcon’ at act.item.c:804:5,
inlined from ‘name_from_drinkcon’ at act.item.c:769:6:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:136:10: warning: ‘__builtin_strncat’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
136 | return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
act.item.c: In function ‘name_from_drinkcon’:
act.item.c:797:16: note: length computed here
797 | cpylen = strlen(cur_name);
| ^~~~~~~~~~~~~~~~

* Whitespace cleanup before bugfix

* Fix warnings for gcc-9.2.1

Also, fixed an ancient FIXME and a known bad strcat usage.

spell_parser.c: In function ‘say_spell’:
spell_parser.c:135:75: warning: ‘%s’ directive output may be truncated writing up to 255 bytes into a region of size 216 [-Wformat-truncation=]
135 | snprintf(buf1, sizeof(buf1), "$n stares at you and utters the words, '%s'.",
| ^~
In file included from /usr/include/stdio.h:867,
from sysdep.h:69,
from spell_parser.c:12:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:67:10: note: ‘__builtin___snprintf_chk’ output between 43 and 298 bytes into a destination of size 256
This commit is contained in:
Thomas Arp
2020-03-08 13:33:59 +01:00
committed by GitHub
parent eb650c2811
commit 6fede208d2
2 changed files with 271 additions and 296 deletions

View File

@@ -770,7 +770,7 @@ void name_from_drinkcon(struct obj_data *obj)
{ {
char *new_name, *cur_name, *next; char *new_name, *cur_name, *next;
const char *liqname; const char *liqname;
int liqlen, cpylen; int liqlen, cpylen, maxlen;
if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN)) if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN))
return; return;
@@ -785,7 +785,8 @@ void name_from_drinkcon(struct obj_data *obj)
} }
liqlen = strlen(liqname); liqlen = strlen(liqname);
CREATE(new_name, char, strlen(obj->name) - strlen(liqname)); /* +1 for NUL, -1 for space */ maxlen = strlen(obj->name) - strlen(liqname); /* +1 for NUL, -1 for space */
CREATE(new_name, char, maxlen);
for (cur_name = obj->name; cur_name; cur_name = next) { for (cur_name = obj->name; cur_name; cur_name = next) {
if (*cur_name == ' ') if (*cur_name == ' ')
@@ -799,9 +800,13 @@ void name_from_drinkcon(struct obj_data *obj)
if (!strn_cmp(cur_name, liqname, liqlen)) if (!strn_cmp(cur_name, liqname, liqlen))
continue; continue;
if (*new_name) if (*new_name) {
strcat(new_name, " "); /* strcat: OK (size precalculated) */ strcat(new_name, " "); /* strcat: OK (size precalculated) */
strncat(new_name, cur_name, cpylen); /* strncat: OK (size precalculated) */ maxlen--;
}
strncat(new_name, cur_name, maxlen); /* strncat: OK (size precalculated) */
maxlen -= cpylen;
} }
if (GET_OBJ_RNUM(obj) == NOTHING || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name) if (GET_OBJ_RNUM(obj) == NOTHING || obj->name != obj_proto[GET_OBJ_RNUM(obj)].name)

View File

@@ -1,12 +1,12 @@
/************************************************************************** /**************************************************************************
* File: spell_parser.c Part of tbaMUD * * File: spell_parser.c Part of tbaMUD *
* Usage: Top-level magic routines; outside points of entry to magic sys. * * Usage: Top-level magic routines; outside points of entry to magic sys. *
* * * *
* All rights reserved. See license for complete information. * * All rights reserved. See license for complete information. *
* * * *
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
**************************************************************************/ **************************************************************************/
#include "conf.h" #include "conf.h"
#include "sysdep.h" #include "sysdep.h"
@@ -28,8 +28,11 @@ char cast_arg2[MAX_INPUT_LENGTH];
const char *unused_spellname = "!UNUSED!"; /* So we can get &unused_spellname */ const char *unused_spellname = "!UNUSED!"; /* So we can get &unused_spellname */
/* Local (File Scope) Function Prototypes */ /* Local (File Scope) Function Prototypes */
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch, struct obj_data *tobj); static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
static void spello(int spl, const char *name, int max_mana, int min_mana, int mana_change, int minpos, int targets, int violent, int routines, const char *wearoff); struct obj_data *tobj);
static void spello(int spl, const char *name, int max_mana, int min_mana,
int mana_change, int minpos, int targets, int violent, int routines,
const char *wearoff);
static int mag_manacost(struct char_data *ch, int spellnum); static int mag_manacost(struct char_data *ch, int spellnum);
/* Local (File Scope) Variables */ /* Local (File Scope) Variables */
@@ -37,112 +40,100 @@ struct syllable {
const char *org; const char *org;
const char *news; const char *news;
}; };
static struct syllable syls[] = { static struct syllable syls[] = { { " ", " " }, { "ar", "abra" },
{" ", " "}, { "ate", "i" }, { "cau", "kada" }, { "blind", "nose" }, { "bur", "mosa" }, {
{"ar", "abra"}, "cu", "judi" }, { "de", "oculo" }, { "dis", "mar" },
{"ate", "i"}, { "ect", "kamina" }, { "en", "uns" }, { "gro", "cra" }, { "light", "dies" },
{"cau", "kada"}, { "lo", "hi" }, { "magi", "kari" }, { "mon", "bar" }, { "mor", "zak" }, {
{"blind", "nose"}, "move", "sido" }, { "ness", "lacri" }, { "ning", "illa" }, { "per",
{"bur", "mosa"}, "duda" }, { "ra", "gru" }, { "re", "candus" }, { "son", "sabru" }, {
{"cu", "judi"}, "tect", "infra" }, { "tri", "cula" }, { "ven", "nofo" }, { "word of",
{"de", "oculo"}, "inset" }, { "a", "i" }, { "b", "v" }, { "c", "q" }, { "d", "m" }, {
{"dis", "mar"}, "e", "o" }, { "f", "y" }, { "g", "t" }, { "h", "p" }, { "i", "u" }, {
{"ect", "kamina"}, "j", "y" }, { "k", "t" }, { "l", "r" }, { "m", "w" }, { "n", "b" }, {
{"en", "uns"}, "o", "a" }, { "p", "s" }, { "q", "d" }, { "r", "f" }, { "s", "g" }, {
{"gro", "cra"}, "t", "h" }, { "u", "e" }, { "v", "z" }, { "w", "x" }, { "x", "n" }, {
{"light", "dies"}, "y", "l" }, { "z", "k" }, { "", "" } };
{"lo", "hi"},
{"magi", "kari"},
{"mon", "bar"},
{"mor", "zak"},
{"move", "sido"},
{"ness", "lacri"},
{"ning", "illa"},
{"per", "duda"},
{"ra", "gru"},
{"re", "candus"},
{"son", "sabru"},
{"tect", "infra"},
{"tri", "cula"},
{"ven", "nofo"},
{"word of", "inset"},
{"a", "i"}, {"b", "v"}, {"c", "q"}, {"d", "m"}, {"e", "o"}, {"f", "y"}, {"g", "t"},
{"h", "p"}, {"i", "u"}, {"j", "y"}, {"k", "t"}, {"l", "r"}, {"m", "w"}, {"n", "b"},
{"o", "a"}, {"p", "s"}, {"q", "d"}, {"r", "f"}, {"s", "g"}, {"t", "h"}, {"u", "e"},
{"v", "z"}, {"w", "x"}, {"x", "n"}, {"y", "l"}, {"z", "k"}, {"", ""}
};
static int mag_manacost(struct char_data *ch, int spellnum) {
static int mag_manacost(struct char_data *ch, int spellnum)
{
return MAX(SINFO.mana_max - (SINFO.mana_change * return MAX(SINFO.mana_max - (SINFO.mana_change *
(GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])), (GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])),
SINFO.mana_min); SINFO.mana_min);
} }
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch, static char *obfuscate_spell(const char *unobfuscated) {
struct obj_data *tobj) static char obfuscated[200];
{ int maxlen = 200;
char lbuf[256], buf[256], buf1[256], buf2[256]; /* FIXME */
const char *format;
struct char_data *i;
int j, ofs = 0; int j, ofs = 0;
*buf = '\0'; *obfuscated = '\0';
strlcpy(lbuf, skill_name(spellnum), sizeof(lbuf));
while (lbuf[ofs]) { while (unobfuscated[ofs]) {
for (j = 0; *(syls[j].org); j++) { for (j = 0; *(syls[j].org); j++) {
if (!strncmp(syls[j].org, lbuf + ofs, strlen(syls[j].org))) { if (!strncmp(syls[j].org, unobfuscated + ofs, strlen(syls[j].org))) {
strcat(buf, syls[j].news); /* strcat: BAD */ if (strlen(syls[j].news) < maxlen) {
strncat(obfuscated, syls[j].news, maxlen);
maxlen -= strlen(syls[j].news);
} else {
log("No room in obfuscated version of '%s' (currently obfuscated to '%s') to add syllable '%s'.",
unobfuscated, obfuscated, syls[j].news);
}
ofs += strlen(syls[j].org); ofs += strlen(syls[j].org);
break; break;
} }
} }
/* i.e., we didn't find a match in syls[] */ /* i.e., we didn't find a match in syls[] */
if (!*syls[j].org) { if (!*syls[j].org) {
log("No entry in syllable table for substring of '%s'", lbuf); log("No entry in syllable table for substring of '%s' starting at '%s'.", unobfuscated, unobfuscated + ofs);
ofs++; ofs++;
} }
} }
return obfuscated;
}
static void say_spell(struct char_data *ch, int spellnum, struct char_data *tch,
struct obj_data *tobj) {
const char *format, *spell = skill_name(spellnum);
char act_buf_original[256], act_buf_obfuscated[256], *obfuscated = obfuscate_spell(spell);
struct char_data *i;
if (tch != NULL && IN_ROOM(tch) == IN_ROOM(ch)) { if (tch != NULL && IN_ROOM(tch) == IN_ROOM(ch)) {
if (tch == ch) if (tch == ch)
format = "$n closes $s eyes and utters the words, '%s'."; format = "$n closes $s eyes and utters the words, '%s'.";
else else
format = "$n stares at $N and utters the words, '%s'."; format = "$n stares at $N and utters the words, '%s'.";
} else if (tobj != NULL && } else if (tobj != NULL
((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch))) && ((IN_ROOM(tobj) == IN_ROOM(ch)) || (tobj->carried_by == ch)))
format = "$n stares at $p and utters the words, '%s'."; format = "$n stares at $p and utters the words, '%s'.";
else else
format = "$n utters the words, '%s'."; format = "$n utters the words, '%s'.";
snprintf(buf1, sizeof(buf1), format, skill_name(spellnum)); snprintf(act_buf_original, sizeof(act_buf_original), format, spell);
snprintf(buf2, sizeof(buf2), format, buf); snprintf(act_buf_obfuscated, sizeof(act_buf_obfuscated), format, obfuscated);
for (i = world[IN_ROOM(ch)].people; i; i = i->next_in_room) { for (i = world[IN_ROOM(ch)].people; i; i = i->next_in_room) {
if (i == ch || i == tch || !i->desc || !AWAKE(i)) if (i == ch || i == tch || !i->desc || !AWAKE(i))
continue; continue;
if (GET_CLASS(ch) == GET_CLASS(i)) if (GET_CLASS(ch) == GET_CLASS(i))
perform_act(buf1, ch, tobj, tch, i); perform_act(act_buf_original, ch, tobj, tch, i);
else else
perform_act(buf2, ch, tobj, tch, i); perform_act(act_buf_obfuscated, ch, tobj, tch, i);
} }
if (tch != NULL && tch != ch && IN_ROOM(tch) == IN_ROOM(ch)) { if (tch != NULL && tch != ch && IN_ROOM(tch) == IN_ROOM(ch)) {
snprintf(buf1, sizeof(buf1), "$n stares at you and utters the words, '%s'.", snprintf(act_buf_original, sizeof(act_buf_original), "$n stares at you and utters the words, '%s'.",
GET_CLASS(ch) == GET_CLASS(tch) ? skill_name(spellnum) : buf); GET_CLASS(ch) == GET_CLASS(tch) ? spell : obfuscated);
act(buf1, FALSE, ch, NULL, tch, TO_VICT); act(act_buf_original, FALSE, ch, NULL, tch, TO_VICT);
} }
} }
/* This function should be used anytime you are not 100% sure that you have /* This function should be used anytime you are not 100% sure that you have
* a valid spell/skill number. A typical for() loop would not need to use * a valid spell/skill number. A typical for() loop would not need to use
* this because you can guarantee > 0 and <= TOP_SPELL_DEFINE. */ * this because you can guarantee > 0 and <= TOP_SPELL_DEFINE. */
const char *skill_name(int num) const char *skill_name(int num) {
{
if (num > 0 && num <= TOP_SPELL_DEFINE) if (num > 0 && num <= TOP_SPELL_DEFINE)
return (spell_info[num].name); return (spell_info[num].name);
else if (num == -1) else if (num == -1)
@@ -151,8 +142,7 @@ const char *skill_name(int num)
return ("UNDEFINED"); return ("UNDEFINED");
} }
int find_skill_num(char *name) int find_skill_num(char *name) {
{
int skindex, ok; int skindex, ok;
char *temp, *temp2; char *temp, *temp2;
char first[256], first2[256], tempbuf[256]; char first[256], first2[256], tempbuf[256];
@@ -185,8 +175,7 @@ int find_skill_num(char *name)
* point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently * point for non-spoken or unrestricted spells. Spellnum 0 is legal but silently
* ignored here, to make callers simpler. */ * ignored here, to make callers simpler. */
int call_magic(struct char_data *caster, struct char_data *cvict, int call_magic(struct char_data *caster, struct char_data *cvict,
struct obj_data *ovict, int spellnum, int level, int casttype) struct obj_data *ovict, int spellnum, int level, int casttype) {
{
int savetype; int savetype;
if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE) if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE)
@@ -204,8 +193,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
act("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM); act("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM);
return (0); return (0);
} }
if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && if (ROOM_FLAGGED(IN_ROOM(caster), ROOM_PEACEFUL) && (SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) {
(SINFO.violent || IS_SET(SINFO.routines, MAG_DAMAGE))) {
send_to_char(caster, "A flash of white light fills the room, dispelling your violent magic!\r\n"); send_to_char(caster, "A flash of white light fills the room, dispelling your violent magic!\r\n");
act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM); act("White light from no particular source suddenly fills the room, then vanishes.", FALSE, caster, 0, 0, TO_ROOM);
return (0); return (0);
@@ -266,15 +254,42 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
if (IS_SET(SINFO.routines, MAG_MANUAL)) if (IS_SET(SINFO.routines, MAG_MANUAL))
switch (spellnum) { switch (spellnum) {
case SPELL_CHARM: MANUAL_SPELL(spell_charm); break; case SPELL_CHARM:
case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break; MANUAL_SPELL(spell_charm)
case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break; ;
case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break; break;
case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break; case SPELL_CREATE_WATER:
case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break; MANUAL_SPELL(spell_create_water)
case SPELL_SUMMON: MANUAL_SPELL(spell_summon); break; ;
case SPELL_WORD_OF_RECALL: MANUAL_SPELL(spell_recall); break; break;
case SPELL_TELEPORT: MANUAL_SPELL(spell_teleport); break; case SPELL_DETECT_POISON:
MANUAL_SPELL(spell_detect_poison)
;
break;
case SPELL_ENCHANT_WEAPON:
MANUAL_SPELL(spell_enchant_weapon)
;
break;
case SPELL_IDENTIFY:
MANUAL_SPELL(spell_identify)
;
break;
case SPELL_LOCATE_OBJECT:
MANUAL_SPELL(spell_locate_object)
;
break;
case SPELL_SUMMON:
MANUAL_SPELL(spell_summon)
;
break;
case SPELL_WORD_OF_RECALL:
MANUAL_SPELL(spell_recall)
;
break;
case SPELL_TELEPORT:
MANUAL_SPELL(spell_teleport)
;
break;
} }
return (1); return (1);
@@ -289,9 +304,7 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
* potion - [0] level [1] spell num [2] spell num [3] spell num * potion - [0] level [1] spell num [2] spell num [3] spell num
* Staves and wands will default to level 14 if the level is not specified; the * Staves and wands will default to level 14 if the level is not specified; the
* DikuMUD format did not specify staff and wand levels in the world files */ * DikuMUD format did not specify staff and wand levels in the world files */
void mag_objectmagic(struct char_data *ch, struct obj_data *obj, void mag_objectmagic(struct char_data *ch, struct obj_data *obj, char *argument) {
char *argument)
{
char arg[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH];
int i, k; int i, k;
struct char_data *tch = NULL, *next_tch; struct char_data *tch = NULL, *next_tch;
@@ -322,7 +335,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
/* Area/mass spells on staves can cause crashes. So we use special cases /* Area/mass spells on staves can cause crashes. So we use special cases
* for those spells spells here. */ * for those spells spells here. */
if (HAS_SPELL_ROUTINE(GET_OBJ_VAL(obj, 3), MAG_MASSES | MAG_AREAS)) { if (HAS_SPELL_ROUTINE(GET_OBJ_VAL(obj, 3), MAG_MASSES | MAG_AREAS)) {
for (i = 0, tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room) for (i = 0, tch = world[IN_ROOM(ch)].people; tch;
tch = tch->next_in_room)
i++; i++;
while (i-- > 0) while (i-- > 0)
call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF); call_magic(ch, NULL, NULL, GET_OBJ_VAL(obj, 3), k, CAST_STAFF);
@@ -353,7 +367,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
act(obj->action_description, FALSE, ch, obj, tobj, TO_ROOM); act(obj->action_description, FALSE, ch, obj, tobj, TO_ROOM);
else else
act("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM); act("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM);
} else if (IS_SET(spell_info[GET_OBJ_VAL(obj, 3)].routines, MAG_AREAS | MAG_MASSES)) { } else if (IS_SET(spell_info[GET_OBJ_VAL(obj, 3)].routines,
MAG_AREAS | MAG_MASSES)) {
/* Wands with area spells don't need to be pointed. */ /* Wands with area spells don't need to be pointed. */
act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR); act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR);
act("$n points $p outward.", TRUE, ch, obj, NULL, TO_ROOM); act("$n points $p outward.", TRUE, ch, obj, NULL, TO_ROOM);
@@ -370,8 +385,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
GET_OBJ_VAL(obj, 2)--; GET_OBJ_VAL(obj, 2)--;
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
if (GET_OBJ_VAL(obj, 0)) if (GET_OBJ_VAL(obj, 0))
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_WAND); CAST_WAND);
else else
call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3), call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, 3),
DEFAULT_WAND_LVL, CAST_WAND); DEFAULT_WAND_LVL, CAST_WAND);
@@ -379,8 +394,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
case ITEM_SCROLL: case ITEM_SCROLL:
if (*arg) { if (*arg) {
if (!k) { if (!k) {
act("There is nothing to here to affect with $p.", FALSE, act("There is nothing to here to affect with $p.", FALSE, ch, obj, NULL,
ch, obj, NULL, TO_CHAR); TO_CHAR);
return; return;
} }
} else } else
@@ -394,8 +409,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
for (i = 1; i <= 3; i++) for (i = 1; i <= 3; i++)
if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i), if (call_magic(ch, tch, tobj, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_SCROLL) <= 0) CAST_SCROLL) <= 0)
break; break;
if (obj != NULL) if (obj != NULL)
@@ -415,8 +430,8 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
WAIT_STATE(ch, PULSE_VIOLENCE); WAIT_STATE(ch, PULSE_VIOLENCE);
for (i = 1; i <= 3; i++) for (i = 1; i <= 3; i++)
if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i), if (call_magic(ch, ch, NULL, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0),
GET_OBJ_VAL(obj, 0), CAST_POTION) <= 0) CAST_POTION) <= 0)
break; break;
if (obj != NULL) if (obj != NULL)
@@ -434,8 +449,7 @@ void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
* prints the words, etc. Entry point for NPC casts. Recommended entry point * prints the words, etc. Entry point for NPC casts. Recommended entry point
* for spells cast by NPCs via specprocs. */ * for spells cast by NPCs via specprocs. */
int cast_spell(struct char_data *ch, struct char_data *tch, int cast_spell(struct char_data *ch, struct char_data *tch,
struct obj_data *tobj, int spellnum) struct obj_data *tobj, int spellnum) {
{
if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) { if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) {
log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum, log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum,
TOP_SPELL_DEFINE); TOP_SPELL_DEFINE);
@@ -488,8 +502,7 @@ int cast_spell(struct char_data *ch, struct char_data *tch,
* determines the spell number and finds a target, throws the die to see if * determines the spell number and finds a target, throws the die to see if
* the spell can be cast, checks for sufficient mana and subtracts it, and * the spell can be cast, checks for sufficient mana and subtracts it, and
* passes control to cast_spell(). */ * passes control to cast_spell(). */
ACMD(do_cast) ACMD(do_cast) {
{
struct char_data *tch = NULL; struct char_data *tch = NULL;
struct obj_data *tobj = NULL; struct obj_data *tobj = NULL;
char *s, *t; char *s, *t;
@@ -507,7 +520,8 @@ ACMD(do_cast)
} }
s = strtok(NULL, "'"); s = strtok(NULL, "'");
if (s == NULL) { if (s == NULL) {
send_to_char(ch, "Spell names must be enclosed in the Holy Magic Symbols: '\r\n"); send_to_char(ch,
"Spell names must be enclosed in the Holy Magic Symbols: '\r\n");
return; return;
} }
t = strtok(NULL, "\0"); t = strtok(NULL, "\0");
@@ -564,7 +578,8 @@ ACMD(do_cast)
} }
} }
if (!target && IS_SET(SINFO.targets, TAR_OBJ_ROOM)) if (!target && IS_SET(SINFO.targets, TAR_OBJ_ROOM))
if ((tobj = get_obj_in_list_vis(ch, t, &number, world[IN_ROOM(ch)].contents)) != NULL) if ((tobj = get_obj_in_list_vis(ch, t, &number,
world[IN_ROOM(ch)].contents)) != NULL)
target = TRUE; target = TRUE;
if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD)) if (!target && IS_SET(SINFO.targets, TAR_OBJ_WORLD))
@@ -583,14 +598,14 @@ ACMD(do_cast)
target = TRUE; target = TRUE;
} }
/* if no target specified, and the spell isn't violent, default to self */ /* if no target specified, and the spell isn't violent, default to self */
if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) && if (!target && IS_SET(SINFO.targets, TAR_CHAR_ROOM) && !SINFO.violent) {
!SINFO.violent) {
tch = ch; tch = ch;
target = TRUE; target = TRUE;
} }
if (!target) { if (!target) {
send_to_char(ch, "Upon %s should the spell be cast?\r\n", send_to_char(ch, "Upon %s should the spell be cast?\r\n",
IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ? "what" : "who"); IS_SET(SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD | TAR_OBJ_EQUIP) ?
"what" : "who");
return; return;
} }
} }
@@ -627,12 +642,12 @@ ACMD(do_cast)
} }
} }
void spell_level(int spell, int chclass, int level) void spell_level(int spell, int chclass, int level) {
{
int bad = 0; int bad = 0;
if (spell < 0 || spell > TOP_SPELL_DEFINE) { if (spell < 0 || spell > TOP_SPELL_DEFINE) {
log("SYSERR: attempting assign to illegal spellnum %d/%d", spell, TOP_SPELL_DEFINE); log("SYSERR: attempting assign to illegal spellnum %d/%d", spell,
TOP_SPELL_DEFINE);
return; return;
} }
@@ -652,11 +667,10 @@ void spell_level(int spell, int chclass, int level)
spell_info[spell].min_level[chclass] = level; spell_info[spell].min_level[chclass] = level;
} }
/* Assign the spells on boot up */ /* Assign the spells on boot up */
static void spello(int spl, const char *name, int max_mana, int min_mana, static void spello(int spl, const char *name, int max_mana, int min_mana,
int mana_change, int minpos, int targets, int violent, int routines, const char *wearoff) int mana_change, int minpos, int targets, int violent, int routines,
{ const char *wearoff) {
int i; int i;
for (i = 0; i < NUM_CLASSES; i++) for (i = 0; i < NUM_CLASSES; i++)
@@ -672,8 +686,7 @@ static void spello(int spl, const char *name, int max_mana, int min_mana,
spell_info[spl].wear_off_msg = wearoff; spell_info[spl].wear_off_msg = wearoff;
} }
void unused_spell(int spl) void unused_spell(int spl) {
{
int i; int i;
for (i = 0; i < NUM_CLASSES; i++) for (i = 0; i < NUM_CLASSES; i++)
@@ -713,8 +726,7 @@ void unused_spell(int spl)
* See the documentation for a more detailed description of these fields. You * See the documentation for a more detailed description of these fields. You
* only need a spello() call to define a new spell; to decide who gets to use * only need a spello() call to define a new spell; to decide who gets to use
* a spell or skill, look in class.c. -JE */ * a spell or skill, look in class.c. -JE */
void mag_assign_spells(void) void mag_assign_spells(void) {
{
int i; int i;
/* Do not change the loop below. */ /* Do not change the loop below. */
@@ -723,12 +735,10 @@ void mag_assign_spells(void)
/* Do not change the loop above. */ /* Do not change the loop above. */
spello(SPELL_ANIMATE_DEAD, "animate dead", 35, 10, 3, POS_STANDING, spello(SPELL_ANIMATE_DEAD, "animate dead", 35, 10, 3, POS_STANDING,
TAR_OBJ_ROOM, FALSE, MAG_SUMMONS, TAR_OBJ_ROOM, FALSE, MAG_SUMMONS, NULL);
NULL);
spello(SPELL_ARMOR, "armor", 30, 15, 3, POS_FIGHTING, spello(SPELL_ARMOR, "armor", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel less protected.");
"You feel less protected.");
spello(SPELL_BLESS, "bless", 35, 5, 3, POS_STANDING, spello(SPELL_BLESS, "bless", 35, 5, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS,
@@ -739,12 +749,10 @@ void mag_assign_spells(void)
"You feel a cloak of blindness dissolve."); "You feel a cloak of blindness dissolve.");
spello(SPELL_BURNING_HANDS, "burning hands", 30, 10, 3, POS_FIGHTING, spello(SPELL_BURNING_HANDS, "burning hands", 30, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CALL_LIGHTNING, "call lightning", 40, 25, 3, POS_FIGHTING, spello(SPELL_CALL_LIGHTNING, "call lightning", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CHARM, "charm person", 75, 50, 2, POS_FIGHTING, spello(SPELL_CHARM, "charm person", 75, 50, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL,
@@ -755,48 +763,38 @@ void mag_assign_spells(void)
"You feel your strength return."); "You feel your strength return.");
spello(SPELL_CLONE, "clone", 80, 65, 5, POS_STANDING, spello(SPELL_CLONE, "clone", 80, 65, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_SUMMONS, TAR_IGNORE, FALSE, MAG_SUMMONS, NULL);
NULL);
spello(SPELL_COLOR_SPRAY, "color spray", 30, 15, 3, POS_FIGHTING, spello(SPELL_COLOR_SPRAY, "color spray", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_CONTROL_WEATHER, "control weather", 75, 25, 5, POS_STANDING, spello(SPELL_CONTROL_WEATHER, "control weather", 75, 25, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_MANUAL, TAR_IGNORE, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_CREATE_FOOD, "create food", 30, 5, 4, POS_STANDING, spello(SPELL_CREATE_FOOD, "create food", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_CREATIONS, TAR_IGNORE, FALSE, MAG_CREATIONS, NULL);
NULL);
spello(SPELL_CREATE_WATER, "create water", 30, 5, 4, POS_STANDING, spello(SPELL_CREATE_WATER, "create water", 30, 5, 4, POS_STANDING,
TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL, TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_CURE_BLIND, "cure blind", 30, 5, 2, POS_STANDING, spello(SPELL_CURE_BLIND, "cure blind", 30, 5, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS, TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS, NULL);
NULL);
spello(SPELL_CURE_CRITIC, "cure critic", 30, 10, 2, POS_FIGHTING, spello(SPELL_CURE_CRITIC, "cure critic", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
NULL);
spello(SPELL_CURE_LIGHT, "cure light", 30, 10, 2, POS_FIGHTING, spello(SPELL_CURE_LIGHT, "cure light", 30, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS, NULL);
NULL);
spello(SPELL_CURSE, "curse", 80, 50, 2, POS_STANDING, spello(SPELL_CURSE, "curse", 80, 50, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS,
"You feel more optimistic."); "You feel more optimistic.");
spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING, spello(SPELL_DARKNESS, "darkness", 30, 5, 4, POS_STANDING,
TAR_IGNORE, FALSE, MAG_ROOMS, TAR_IGNORE, FALSE, MAG_ROOMS, NULL);
NULL);
spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING, spello(SPELL_DETECT_ALIGN, "detect alignment", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, "You feel less aware.");
"You feel less aware.");
spello(SPELL_DETECT_INVIS, "detect invisibility", 20, 10, 2, POS_STANDING, spello(SPELL_DETECT_INVIS, "detect invisibility", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
@@ -811,73 +809,58 @@ void mag_assign_spells(void)
"The detect poison wears off."); "The detect poison wears off.");
spello(SPELL_DISPEL_EVIL, "dispel evil", 40, 25, 3, POS_FIGHTING, spello(SPELL_DISPEL_EVIL, "dispel evil", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_DISPEL_GOOD, "dispel good", 40, 25, 3, POS_FIGHTING, spello(SPELL_DISPEL_GOOD, "dispel good", 40, 25, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING, spello(SPELL_EARTHQUAKE, "earthquake", 40, 25, 3, POS_FIGHTING,
TAR_IGNORE, TRUE, MAG_AREAS, TAR_IGNORE, TRUE, MAG_AREAS, NULL);
NULL);
spello(SPELL_ENCHANT_WEAPON, "enchant weapon", 150, 100, 10, POS_STANDING, spello(SPELL_ENCHANT_WEAPON, "enchant weapon", 150, 100, 10, POS_STANDING,
TAR_OBJ_INV, FALSE, MAG_MANUAL, TAR_OBJ_INV, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_ENERGY_DRAIN, "energy drain", 40, 25, 1, POS_FIGHTING, spello(SPELL_ENERGY_DRAIN, "energy drain", 40, 25, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE | MAG_MANUAL, NULL);
NULL);
spello(SPELL_GROUP_ARMOR, "group armor", 50, 30, 2, POS_STANDING, spello(SPELL_GROUP_ARMOR, "group armor", 50, 30, 2, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS, TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
NULL);
spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING, spello(SPELL_FIREBALL, "fireball", 40, 30, 2, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING, spello(SPELL_FLY, "fly", 40, 20, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You drift slowly to the ground.");
"You drift slowly to the ground.");
spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING, spello(SPELL_GROUP_HEAL, "group heal", 80, 60, 5, POS_STANDING,
TAR_IGNORE, FALSE, MAG_GROUPS, TAR_IGNORE, FALSE, MAG_GROUPS, NULL);
NULL);
spello(SPELL_HARM, "harm", 75, 45, 3, POS_FIGHTING, spello(SPELL_HARM, "harm", 75, 45, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_HEAL, "heal", 60, 40, 3, POS_FIGHTING, spello(SPELL_HEAL, "heal", 60, 40, 3, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS, TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_UNAFFECTS, NULL);
NULL);
spello(SPELL_INFRAVISION, "infravision", 25, 10, 1, POS_STANDING, spello(SPELL_INFRAVISION, "infravision", 25, 10, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"Your night vision seems to fade."); "Your night vision seems to fade.");
spello(SPELL_INVISIBLE, "invisibility", 35, 25, 1, POS_STANDING, spello(SPELL_INVISIBLE, "invisibility", 35, 25, 1, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
"You feel yourself exposed."); MAG_AFFECTS | MAG_ALTER_OBJS, "You feel yourself exposed.");
spello(SPELL_LIGHTNING_BOLT, "lightning bolt", 30, 15, 1, POS_FIGHTING, spello(SPELL_LIGHTNING_BOLT, "lightning bolt", 30, 15, 1, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_LOCATE_OBJECT, "locate object", 25, 20, 1, POS_STANDING, spello(SPELL_LOCATE_OBJECT, "locate object", 25, 20, 1, POS_STANDING,
TAR_OBJ_WORLD, FALSE, MAG_MANUAL, TAR_OBJ_WORLD, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_MAGIC_MISSILE, "magic missile", 25, 10, 3, POS_FIGHTING, spello(SPELL_MAGIC_MISSILE, "magic missile", 25, 10, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_POISON, "poison", 50, 20, 3, POS_STANDING, spello(SPELL_POISON, "poison", 50, 20, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE, TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE,
MAG_AFFECTS | MAG_ALTER_OBJS, MAG_AFFECTS | MAG_ALTER_OBJS, "You feel less sick.");
"You feel less sick.");
spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING, spello(SPELL_PROT_FROM_EVIL, "protection from evil", 40, 10, 3, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
@@ -885,63 +868,50 @@ void mag_assign_spells(void)
spello(SPELL_REMOVE_CURSE, "remove curse", 45, 25, 5, POS_STANDING, spello(SPELL_REMOVE_CURSE, "remove curse", 45, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE,
MAG_UNAFFECTS | MAG_ALTER_OBJS, MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
NULL);
spello(SPELL_REMOVE_POISON, "remove poison", 40, 8, 4, POS_STANDING, spello(SPELL_REMOVE_POISON, "remove poison", 40, 8, 4, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_UNAFFECTS | MAG_ALTER_OBJS, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE,
NULL); MAG_UNAFFECTS | MAG_ALTER_OBJS, NULL);
spello(SPELL_SANCTUARY, "sanctuary", 110, 85, 5, POS_STANDING, spello(SPELL_SANCTUARY, "sanctuary", 110, 85, 5, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "The white aura around your body fades.");
"The white aura around your body fades.");
spello(SPELL_SENSE_LIFE, "sense life", 20, 10, 2, POS_STANDING, spello(SPELL_SENSE_LIFE, "sense life", 20, 10, 2, POS_STANDING,
TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS,
"You feel less aware of your surroundings."); "You feel less aware of your surroundings.");
spello(SPELL_SHOCKING_GRASP, "shocking grasp", 30, 15, 3, POS_FIGHTING, spello(SPELL_SHOCKING_GRASP, "shocking grasp", 30, 15, 3, POS_FIGHTING,
TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, TAR_CHAR_ROOM | TAR_FIGHT_VICT, TRUE, MAG_DAMAGE, NULL);
NULL);
spello(SPELL_SLEEP, "sleep", 40, 25, 5, POS_STANDING, spello(SPELL_SLEEP, "sleep", 40, 25, 5, POS_STANDING,
TAR_CHAR_ROOM, TRUE, MAG_AFFECTS, TAR_CHAR_ROOM, TRUE, MAG_AFFECTS, "You feel less tired.");
"You feel less tired.");
spello(SPELL_STRENGTH, "strength", 35, 30, 1, POS_STANDING, spello(SPELL_STRENGTH, "strength", 35, 30, 1, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "You feel weaker.");
"You feel weaker.");
spello(SPELL_SUMMON, "summon", 75, 50, 3, POS_STANDING, spello(SPELL_SUMMON, "summon", 75, 50, 3, POS_STANDING,
TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_TELEPORT, "teleport", 75, 50, 3, POS_STANDING, spello(SPELL_TELEPORT, "teleport", 75, 50, 3, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_WATERWALK, "waterwalk", 40, 20, 2, POS_STANDING, spello(SPELL_WATERWALK, "waterwalk", 40, 20, 2, POS_STANDING,
TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS, "Your feet seem less buoyant.");
"Your feet seem less buoyant.");
spello(SPELL_WORD_OF_RECALL, "word of recall", 20, 10, 2, POS_FIGHTING, spello(SPELL_WORD_OF_RECALL, "word of recall", 20, 10, 2, POS_FIGHTING,
TAR_CHAR_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
spello(SPELL_IDENTIFY, "identify", 50, 25, 5, POS_STANDING, spello(SPELL_IDENTIFY, "identify", 50, 25, 5, POS_STANDING,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
/* NON-castable spells should appear below here. */ /* NON-castable spells should appear below here. */
spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0, spello(SPELL_IDENTIFY, "identify", 0, 0, 0, 0,
TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL, NULL);
NULL);
/* you might want to name this one something more fitting to your theme -Welcor*/ /* you might want to name this one something more fitting to your theme -Welcor*/
spello(SPELL_DG_AFFECT, "Script-inflicted", 0, 0, 0, POS_SITTING, spello(SPELL_DG_AFFECT, "Script-inflicted", 0, 0, 0, POS_SITTING,
TAR_IGNORE, TRUE, 0, TAR_IGNORE, TRUE, 0, NULL);
NULL);
/* Declaration of skills - this actually doesn't do anything except set it up /* Declaration of skills - this actually doesn't do anything except set it up
* so that immortals can use these skills by default. The min level to use * so that immortals can use these skills by default. The min level to use