/* ************************************************************************ * File: spell_parser.c Part of CircleMUD * * Usage: top-level magic routines; outside points of entry to magic sys. * * * * All rights reserved. See license.doc for complete information. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "interpreter.h" #include "spells.h" #include "handler.h" #include "comm.h" #include "db.h" struct spell_info_type spell_info[TOP_SPELL_DEFINE + 1]; #define SINFO spell_info[spellnum] extern struct room_data *world; /* * This arrangement is pretty stupid, but the number of skills is limited by * the playerfile. We can arbitrarily increase the number of skills by * increasing the space in the playerfile. Meanwhile, this should provide * ample slots for skills. */ char *spells[] = { "!RESERVED!", /* 0 - reserved */ /* SPELLS */ "armor", /* 1 */ "teleport", "bless", "blindness", "charm person", "clone", "control weather", "create food", "create water", "cure blind", /* 10 */ "cure critic", "cure light", "curse", "detect alignment", "detect invisibility", "detect magic", "detect poison", "earthquake", "enchant weapon", "heal", /* 20 */ "invisibility", "locate object", "poison", "remove curse", "sanctuary", "sleep", "strength", "summon", "word of recall", "remove poison", /* 30 */ "sense life", "animate dead", "group armor", "group heal", "group recall", "infravision", "waterwalk", "stone skin", "fear", "recharge", /* 40 */ "portal", "group stone skin", "locate life", "convergence of power", "mana autus", "resist portal", "regen mana", "home", "word of retreat", "chain footing", /* 50 */ "redirect charge", "!UNUSED", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 55 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 60 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 65 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 70 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 75 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 80 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 85 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 90 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 95 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 100 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 105 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 110 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 115 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 120 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 125 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 130 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 135 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 140 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 145 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 150 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 155 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 160 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 165 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 170 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 175 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 180 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 185 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 190 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 195 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 200 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 205 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 210 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 215 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 220 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 225 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 230 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 235 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 240 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 245 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 250 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 255 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 260 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 265 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 270 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 275 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 280 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 285 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 290 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 295 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 300 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 305 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 310 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 315 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 320 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 325 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 330 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 335 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 340 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 345 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 350 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 355 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 360 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 365 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 370 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 375 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 380 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 385 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 390 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 395 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 400 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 405 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 410 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 415 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 420 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 425 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 430 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 435 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 440 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 445 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 450 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 455 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 460 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 465 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 470 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 475 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 480 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 485 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 490 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 495 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 500 */ /* SKILLS */ "backstab", /* 501 */ "bash", "hide", "kick", "pick lock", "punch", "rescue", "sneak", "steal", "track", /* 510 */ "forage", "scan", "brew", "forge", "scribe", /* 515 */ "speed", "berserk", "camouflage", "blanket", "ram", /* 520 */ "mount", "riding", "tame", "second attack", "third attack", /* 525 */ "listen", "meditate", "repair", "tan", "fillet", /* 530 */ "carve", "dodge", "parry", "avoid", "riposte", /* 535 */ "circle", "trip", "disarm", "target", "adrenaline", /* 540 */ "bloodlust", "carnal rage", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 545 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 550 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 555 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 560 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 565 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 570 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 575 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 580 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 585 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 590 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 595 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 600 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 605 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 610 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 615 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 620 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 625 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 630 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 635 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 640 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 645 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 650 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 655 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 660 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 665 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 670 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 675 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 680 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 685 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 690 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 695 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 700 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 705 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 710 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 715 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 720 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 725 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 730 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 735 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 740 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 745 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 750 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 755 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 760 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 765 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 770 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 775 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 780 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 785 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 790 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 795 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 800 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 805 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 810 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 815 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 820 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 825 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 830 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 835 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 840 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 845 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 850 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 855 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 860 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 865 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 870 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 875 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 880 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 885 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 890 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 895 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 900 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 905 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 910 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 915 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 920 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 925 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 930 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 935 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 940 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 945 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 950 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 955 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 960 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 965 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 970 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 975 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 980 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 985 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 990 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 995 */ "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", "!UNUSED!", /* 1000 */ /* OBJECT SPELLS AND NPC SPELLS/SKILLS */ "identify", /* 1001(?) */ "fire breath", "gas breath", "frost breath", "acid breath", "lightning breath", /* 1005 */ "\n" /* the end */ }; struct syllable { char *org; char *new; }; struct syllable syls[] = { {" ", " "}, {"ar", "abra"}, {"ate", "i"}, {"cau", "kada"}, {"blind", "nose"}, {"bur", "mosa"}, {"cu", "judi"}, {"de", "oculo"}, {"dis", "mar"}, {"ect", "kamina"}, {"en", "uns"}, {"gro", "cra"}, {"light", "dies"}, {"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"}, {"", ""} }; int mag_manacost (struct char_data *ch, int spellnum) { int mana; mana = MAX (SINFO.mana_max - (SINFO.mana_change * (GET_LEVEL (ch) - SINFO.min_level[(int) GET_CLASS (ch)])), SINFO.mana_min); /* If char is affected by mana autus, halve the mana */ if (IS_AFFECTED(ch, AFF_AUTUS)) mana >>= 1; return mana; } /* say_spell erodes buf, buf1, buf2 */ void say_spell (struct char_data *ch, int spellnum, struct char_data *tch, struct obj_data *tobj) { char lbuf[256]; struct char_data *i; int j, ofs = 0; *buf = '\0'; strcpy (lbuf, spells[spellnum]); while (*(lbuf + ofs)) { for (j = 0; *(syls[j].org); j++) { if (!strncmp (syls[j].org, lbuf + ofs, strlen (syls[j].org))) { strcat (buf, syls[j].new); ofs += strlen (syls[j].org); } } } if (tch != NULL && tch->in_room == ch->in_room) { if (tch == ch) sprintf (lbuf, "$n closes $s eyes and utters the words, '%%s'."); else sprintf (lbuf, "$n stares at $N and utters the words, '%%s'."); } else if (tobj != NULL && ((tobj->in_room == ch->in_room) || (tobj->carried_by == ch))) sprintf (lbuf, "$n stares at $p and utters the words, '%%s'."); else sprintf (lbuf, "$n utters the words, '%%s'."); sprintf (buf1, lbuf, spells[spellnum]); sprintf (buf2, lbuf, buf); for (i = world[ch->in_room].people; i; i = i->next_in_room) { if (i == ch || i == tch || !i->desc || !AWAKE (i)) continue; if (GET_CLASS (ch) == GET_CLASS (i)) perform_act (buf1, ch, tobj, tch, i); else perform_act (buf2, ch, tobj, tch, i); } /* Arena mods - Thargor */ /* Why do we take the caster's and the recipient points of view? * Not their view of the events, we use a bystander's desc of the * events, but report to the caster's AND receipient's observers. * We cannot assume that there are other bystanders from which * to look at things through. */ /* From the caster's point of view */ i = OBSERVE_BY(ch); while (i != NULL){ if (GET_CLASS (ch) == GET_CLASS (i)) perform_act (buf1, ch, tobj, tch, i); else perform_act (buf2, ch, tobj, tch, i); i = OBSERVE_BY(i); } if (tch != NULL && tch != ch && tch->in_room == ch->in_room) { /* Arena mods - Thargor */ /* From the receipient's point of view */ i = OBSERVE_BY(tch); while (i != NULL){ if (GET_CLASS (tch) == GET_CLASS (i)) perform_act (buf1, ch, tobj, tch, i); else perform_act (buf2, ch, tobj, tch, i); i = OBSERVE_BY(i); } sprintf (buf1, "$n stares at you and utters the words, '%s'.", GET_CLASS (ch) == GET_CLASS (tch) ? spells[spellnum] : buf); act (buf1, FALSE, ch, NULL, tch, TO_VICT); } } char * skill_name (int num) { int i = 0; if (num <= 0) { if (num == -1) return "UNUSED"; else return "UNDEFINED"; } while (num && *spells[i] != '\n') { num--; i++; } if (*spells[i] != '\n') return spells[i]; else return "UNDEFINED"; } int find_skill_num (char *name) { int index = 0, ok; char *temp, *temp2; char first[256], first2[256]; while (*spells[++index] != '\n') { if (is_abbrev (name, spells[index])) return index; ok = 1; temp = any_one_arg (spells[index], first); temp2 = any_one_arg (name, first2); while (*first && *first2 && ok) { if (!is_abbrev (first2, first)) ok = 0; temp = any_one_arg (temp, first); temp2 = any_one_arg (temp2, first2); } if (ok && !*first2) return index; } return -1; } /* * This function is the very heart of the entire magic system. All * invocations of all types of magic -- objects, spoken and unspoken PC * and NPC spells, the works -- all come through this function eventually. * This is also the entry point for non-spoken or unrestricted spells. * Spellnum 0 is legal but silently ignored here, to make callers simpler. */ int call_magic (struct char_data *caster, struct char_data *cvict, struct obj_data *ovict, int spellnum, int level) { ASPELL(spell_locate_target); ASPELL(spell_home); ASPELL(spell_retreat); if (spellnum < 1 || spellnum > TOP_SPELL_DEFINE) return 0; if (ROOM_FLAGGED (caster->in_room, ROOM_NOMAGIC) && GET_LEVEL (caster) < LVL_IMPL) { send_to_char ("Your magic fizzles out and dies.\r\n", caster); act ("$n's magic fizzles out and dies.", FALSE, caster, 0, 0, TO_ROOM); return 0; } if (GET_LEVEL (caster) < LVL_IMPL && IS_SET (ROOM_FLAGS (caster->in_room), ROOM_PEACEFUL) && (SINFO.violent || IS_SET (SINFO.routines, MAG_DAMAGE))) { send_to_char ("A flash of white light fills the room, dispelling your " "violent magic!\r\n", caster); act ("White light from no particular source suddenly fills the room, " "then vanishes.", FALSE, caster, 0, 0, TO_ROOM); return 0; } if (IS_SET (SINFO.routines, MAG_DAMAGE)) mag_damage (level, caster, cvict, spellnum); if (IS_SET (SINFO.routines, MAG_AFFECTS)) mag_affects (level, caster, cvict, spellnum); if (IS_SET (SINFO.routines, MAG_UNAFFECTS)) mag_unaffects (level, caster, cvict, spellnum); if (IS_SET (SINFO.routines, MAG_POINTS)) mag_points (level, caster, cvict, spellnum); if (IS_SET (SINFO.routines, MAG_ALTER_OBJS)) mag_alter_objs (level, caster, ovict, spellnum); if (IS_SET (SINFO.routines, MAG_GROUPS)) mag_groups (level, caster, spellnum); if (IS_SET (SINFO.routines, MAG_MASSES)) mag_masses (level, caster, spellnum); if (IS_SET (SINFO.routines, MAG_AREAS)) mag_areas (level, caster, spellnum); if (IS_SET (SINFO.routines, MAG_SUMMONS)) mag_summons (level, caster, ovict, spellnum); if (IS_SET (SINFO.routines, MAG_CREATIONS)) mag_creations (level, caster, spellnum); if (IS_SET (SINFO.routines, MAG_MANUAL)) switch (spellnum) { case SPELL_CHARM: MANUAL_SPELL (spell_charm); break; case SPELL_CREATE_WATER: MANUAL_SPELL (spell_create_water); 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_FEAR: MANUAL_SPELL (spell_fear); break; case SPELL_RECHARGE: MANUAL_SPELL (spell_recharge); break; case SPELL_PORTAL: MANUAL_SPELL(spell_portal); break; case SPELL_LOCATE_TARGET: MANUAL_SPELL(spell_locate_target); break; case SPELL_HOME: MANUAL_SPELL(spell_home); break; case SPELL_WORD_OF_RETREAT: MANUAL_SPELL(spell_retreat); break; } return 1; } /* * mag_objectmagic: This is the entry-point for all magic items. This should * only be called by the 'quaff', 'use', 'recite', etc. routines. * * For reference, object values 0-3: * staff - [0] level [1] max charges [2] num charges [3] spell num * wand - [0] level [1] max charges [2] num charges [3] spell num * scroll - [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 DikuMUD format did not specify staff and wand levels in the world * files (this is a CircleMUD enhancement). */ void mag_objectmagic (struct char_data *ch, struct obj_data *obj, char *argument) { int i, k; struct char_data *tch = NULL, *next_tch; struct obj_data *tobj = NULL; one_argument (argument, arg); k = generic_find (arg, FIND_CHAR_ROOM | FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP, ch, &tch, &tobj); if (!IS_NPC(ch) && tch != NULL){ if (!IS_NPC(tch)) if (GET_LEVEL (ch) < LVL_IMMORT && GET_LEVEL(tch) >= LVL_IMMORT){ send_to_char ("A blinding flash of white light dispels your magic!\r\n", ch); act ("$n attempts to cast magic on $N.\r\n" "A blinding flash of white light dispels $n's magic.", FALSE, ch, 0, tch, TO_ROOM); return; } } switch (GET_OBJ_TYPE (obj)) { case ITEM_STAFF: act ("You tap $p three times on the ground.", FALSE, ch, obj, 0, TO_CHAR); if (obj->action_description) act (obj->action_description, FALSE, ch, obj, 0, TO_ROOM); else act ("$n taps $p three times on the ground.", FALSE, ch, obj, 0, TO_ROOM); if (GET_OBJ_VAL (obj, 2) <= 0) { act ("It seems powerless.", FALSE, ch, obj, 0, TO_CHAR); act ("Nothing seems to happen.", FALSE, ch, obj, 0, TO_ROOM); } else { GET_OBJ_VAL (obj, 2)--; WAIT_STATE (ch, PULSE_VIOLENCE); for (tch = world[ch->in_room].people; tch; tch = next_tch) { next_tch = tch->next_in_room; if (ch == tch) continue; if (GET_OBJ_VAL (obj, 0)) call_magic (ch, tch, NULL, GET_OBJ_VAL (obj, 3), GET_OBJ_VAL (obj, 0)); else call_magic (ch, tch, NULL, GET_OBJ_VAL (obj, 3), DEFAULT_STAFF_LVL); } } break; case ITEM_WAND: if (k == FIND_CHAR_ROOM) { if (tch == ch) { act ("You point $p at yourself.", FALSE, ch, obj, 0, TO_CHAR); act ("$n points $p at $mself.", FALSE, ch, obj, 0, TO_ROOM); } else { act ("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR); if (obj->action_description != NULL) act (obj->action_description, FALSE, ch, obj, tch, TO_ROOM); else act ("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM); } } else if (tobj != NULL) { act ("You point $p at $P.", FALSE, ch, obj, tobj, TO_CHAR); if (obj->action_description != NULL) act (obj->action_description, FALSE, ch, obj, tobj, TO_ROOM); else act ("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM); } else { act ("At what should $p be pointed?", FALSE, ch, obj, NULL, TO_CHAR); return; } if (GET_OBJ_VAL (obj, 2) <= 0) { act ("It seems powerless.", FALSE, ch, obj, 0, TO_CHAR); act ("Nothing seems to happen.", FALSE, ch, obj, 0, TO_ROOM); return; } GET_OBJ_VAL (obj, 2)--; WAIT_STATE (ch, PULSE_VIOLENCE); if (GET_OBJ_VAL (obj, 0)) call_magic (ch, tch, tobj, GET_OBJ_VAL (obj, 3), GET_OBJ_VAL (obj, 0)); else call_magic (ch, tch, tobj, GET_OBJ_VAL (obj, 3), DEFAULT_WAND_LVL); break; case ITEM_SCROLL: if (*arg) { if (!k) { act ("There is nothing to here to affect with $p.", FALSE, ch, obj, NULL, TO_CHAR); return; } } else tch = ch; act ("You recite $p which dissolves.", TRUE, ch, obj, 0, TO_CHAR); if (obj->action_description) act (obj->action_description, FALSE, ch, obj, NULL, TO_ROOM); else act ("$n recites $p.", FALSE, ch, obj, NULL, TO_ROOM); WAIT_STATE (ch, PULSE_VIOLENCE); for (i = 1; i < 4; i++) if (!(call_magic (ch, tch, tobj, GET_OBJ_VAL (obj, i), GET_OBJ_VAL (obj, 0)))) break; if (obj != NULL) extract_obj (obj); break; case ITEM_POTION: tch = ch; act ("You quaff $p.", FALSE, ch, obj, NULL, TO_CHAR); if (obj->action_description) act (obj->action_description, FALSE, ch, obj, NULL, TO_ROOM); else act ("$n quaffs $p.", TRUE, ch, obj, NULL, TO_ROOM); WAIT_STATE (ch, PULSE_VIOLENCE); for (i = 1; i < 4; i++) if (!(call_magic (ch, ch, NULL, GET_OBJ_VAL (obj, i), GET_OBJ_VAL (obj, 0)))) break; if (obj != NULL) extract_obj (obj); break; default: log ("SYSERR: Unknown object_type in mag_objectmagic"); break; } } /* * cast_spell is used generically to cast any spoken spell, assuming we * already have the target char/obj and spell number. It checks all * restrictions, etc., prints the words, etc. * * Entry point for NPC casts. Recommended entry point for spells cast * by NPCs via specprocs. */ int cast_spell (struct char_data *ch, struct char_data *tch, struct obj_data *tobj, int spellnum) { char buf[256]; if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) { sprintf (buf, "SYSERR: cast_spell trying to call spellnum %d\n", spellnum); log (buf); return 0; } if (GET_POS (ch) < SINFO.min_position) { switch (GET_POS (ch)) { case POS_SLEEPING: send_to_char ("You dream about great magical powers.\r\n", ch); break; case POS_RESTING: send_to_char ("You cannot concentrate while resting.\r\n", ch); break; case POS_SITTING: send_to_char ("You can't do this sitting!\r\n", ch); break; case POS_FIGHTING: send_to_char ("Impossible! You can't concentrate enough!\r\n", ch); break; default: send_to_char ("You can't do much of anything like this!\r\n", ch); break; } return 0; } if (IS_AFFECTED (ch, AFF_CHARM) && (ch->master == tch)) { send_to_char ("You are afraid you might hurt your master!\r\n", ch); return 0; } if ((tch != ch) && IS_SET (SINFO.targets, TAR_SELF_ONLY)) { send_to_char ("You can only cast this spell upon yourself!\r\n", ch); return 0; } if ((tch == ch) && IS_SET (SINFO.targets, TAR_NOT_SELF)) { send_to_char ("You cannot cast this spell upon yourself!\r\n", ch); return 0; } if (IS_SET (SINFO.routines, MAG_GROUPS) && !IS_AFFECTED (ch, AFF_GROUP)) { send_to_char ("You can't cast this spell if you're not in a group!\r\n", ch); return 0; } send_to_char (OK, ch); say_spell (ch, spellnum, tch, tobj); return (call_magic (ch, tch, tobj, spellnum, GET_LEVEL (ch))); } /* * do_cast is the entry point for PC-casted spells. It parses the arguments, * 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 * passes control to cast_spell(). */ ACMD (do_cast) { struct char_data *tch = NULL; struct obj_data *tobj = NULL; char *s, *t; int mana, spellnum, i, target = 0; if (IS_NPC (ch)) return; /* get: blank, spell name, target name */ s = strtok (argument, "'"); if (s == NULL) { send_to_char ("Cast what where?\r\n", ch); return; } s = strtok (NULL, "'"); if (s == NULL) { send_to_char ("Spell names must be enclosed in the Holy Magic Symbols: '\r\n", ch); return; } t = strtok (NULL, "\0"); /* spellnum = search_block(s, spells, 0); */ spellnum = find_skill_num (s); if ((spellnum < 1) || (spellnum > MAX_SPELLS)) { send_to_char ("Cast what?!?\r\n", ch); return; } if (GET_LEVEL (ch) < SINFO.min_level[(int) GET_CLASS (ch)]) { send_to_char ("You do not know that spell!\r\n", ch); return; } if (GET_SKILL (ch, spellnum) == 0) { send_to_char ("You are unfamiliar with that spell.\r\n", ch); return; } /* Find the target */ if (t != NULL) { one_argument (strcpy (arg, t), t); skip_spaces (&t); } if (IS_SET (SINFO.targets, TAR_IGNORE)) { target = TRUE; } else if (t != NULL && *t) { if (!target && (IS_SET (SINFO.targets, TAR_CHAR_ROOM))) { if ((tch = get_char_room_vis (ch, t)) != NULL) target = TRUE; } if (!target && IS_SET (SINFO.targets, TAR_CHAR_WORLD)) if ((tch = get_char_vis (ch, t))) target = TRUE; if (!target && IS_SET (SINFO.targets, TAR_OBJ_INV)) if ((tobj = get_obj_in_list_vis (ch, t, ch->carrying))) target = TRUE; if (!target && IS_SET (SINFO.targets, TAR_OBJ_EQUIP)) { for (i = 0; !target && i < NUM_WEARS; i++) if (GET_EQ (ch, i) && CAN_SEE_OBJ (ch, GET_EQ (ch, i)) && isname (t, GET_EQ (ch, i)->name)) { tobj = GET_EQ (ch, i); target = TRUE; } } if (!target && IS_SET (SINFO.targets, TAR_OBJ_ROOM)) if ((tobj = get_obj_in_list_vis (ch, t, world[ch->in_room].contents))) target = TRUE; if (!target && IS_SET (SINFO.targets, TAR_OBJ_WORLD)) if ((tobj = get_obj_vis (ch, t))) target = TRUE; } else { /* if target string is empty */ if (!target && IS_SET (SINFO.targets, TAR_FIGHT_SELF)) if (FIGHTING (ch) != NULL) { tch = ch; target = TRUE; } if (!target && IS_SET (SINFO.targets, TAR_FIGHT_VICT)) if (FIGHTING (ch) != NULL) { tch = FIGHTING (ch); target = TRUE; } /* if no target specified, and the spell isn't violent, default to self */ if (!target && IS_SET (SINFO.targets, TAR_CHAR_ROOM) && !SINFO.violent) { tch = ch; target = TRUE; } if (!target) { sprintf (buf, "Upon %s should the spell be cast?\r\n", IS_SET (SINFO.targets, TAR_OBJ_ROOM | TAR_OBJ_INV | TAR_OBJ_WORLD) ? "what" : "who"); send_to_char (buf, ch); return; } } if (target && (tch == ch) && SINFO.violent) { send_to_char ("You shouldn't cast that on yourself -- could be bad for your health!\r\n", ch); return; } if (!target) { send_to_char ("Cannot find the target of your spell!\r\n", ch); return; } mana = mag_manacost (ch, spellnum); if ((mana > 0) && (GET_MANA (ch) < mana) && (GET_LEVEL (ch) < LVL_IMMORT)) { send_to_char ("You haven't the energy to cast that spell!\r\n", ch); return; } /* You throws the dice and you takes your chances.. 101% is total failure */ if (number (0, 101) > GET_SKILL (ch, spellnum)) { WAIT_STATE (ch, PULSE_VIOLENCE); if (!tch || !skill_message (0, ch, tch, spellnum)) send_to_char ("You lost your concentration!\r\n", ch); if (mana > 0) GET_MANA (ch) = MAX (0, MIN (GET_MAX_MANA (ch), GET_MANA (ch) - (mana >> 1))); if (SINFO.violent && tch && IS_NPC (tch)) hit (tch, ch, TYPE_UNDEFINED); } else { /* cast spell returns 1 on success; subtract mana & set waitstate */ if (cast_spell (ch, tch, tobj, spellnum)) { WAIT_STATE (ch, PULSE_VIOLENCE); if (mana > 0) GET_MANA (ch) = MAX (0, MIN (GET_MAX_MANA (ch), GET_MANA (ch) - mana)); } } } void spell_level (int spell, int class, int level) { char buf[256]; int bad = 0; if (spell < 0 || spell > TOP_SPELL_DEFINE) { sprintf (buf, "SYSERR: attempting assign to illegal spellnum %d", spell); log (buf); return; } if (class < 0 || class >= NUM_CLASSES) { sprintf (buf, "SYSERR: assigning '%s' to illegal class %d", skill_name (spell), class); log (buf); bad = 1; } if (level < 1 || level > LVL_IMPL) { sprintf (buf, "SYSERR: assigning '%s' to illegal level %d", skill_name (spell), level); log (buf); bad = 1; } if (!bad) spell_info[spell].min_level[class] = level; } /* Assign the spells on boot up */ void spello (int spl, int max_mana, int min_mana, int mana_change, int minpos, int targets, int violent, int routines) { int i; for (i = 0; i < NUM_CLASSES; i++) spell_info[spl].min_level[i] = LVL_IMMORT; spell_info[spl].mana_max = max_mana; spell_info[spl].mana_min = min_mana; spell_info[spl].mana_change = mana_change; spell_info[spl].min_position = minpos; spell_info[spl].targets = targets; spell_info[spl].violent = violent; spell_info[spl].routines = routines; } void unused_spell (int spl) { int i; for (i = 0; i < NUM_CLASSES; i++) spell_info[spl].min_level[i] = LVL_IMPL + 1; spell_info[spl].mana_max = 0; spell_info[spl].mana_min = 0; spell_info[spl].mana_change = 0; spell_info[spl].min_position = 0; spell_info[spl].targets = 0; spell_info[spl].violent = 0; spell_info[spl].routines = 0; } #define skillo(skill) spello(skill, 0, 0, 0, 0, 0, 0, 0); /* * Arguments for spello calls: * * spellnum, maxmana, minmana, manachng, minpos, targets, violent?, routines. * * spellnum: Number of the spell. Usually the symbolic name as defined in * spells.h (such as SPELL_HEAL). * * maxmana : The maximum mana this spell will take (i.e., the mana it * will take when the player first gets the spell). * * minmana : The minimum mana this spell will take, no matter how high * level the caster is. * * manachng: The change in mana for the spell from level to level. This * number should be positive, but represents the reduction in mana cost as * the caster's level increases. * * minpos : Minimum position the caster must be in for the spell to work * (usually fighting or standing). targets : A "list" of the valid targets * for the spell, joined with bitwise OR ('|'). * * violent : TRUE or FALSE, depending on if this is considered a violent * spell and should not be cast in PEACEFUL rooms or on yourself. Should be * set on any spell that inflicts damage, is considered aggressive (i.e. * charm, curse), or is otherwise nasty. * * routines: A list of magic routines which are associated with this spell * if the spell uses spell templates. Also joined with bitwise OR ('|'). * * See the CircleMUD documentation for a more detailed description of these * fields. */ /* * NOTE: SPELL LEVELS ARE NO LONGER ASSIGNED HERE AS OF Circle 3.0 bpl9. * In order to make this cleaner, as well as to make adding new classes * much easier, spell levels are now assigned in class.c. You 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 5 Feb 1996 */ void mag_assign_spells (void) { int i; /* Do not change the loop below */ for (i = 1; i <= TOP_SPELL_DEFINE; i++) unused_spell (i); /* Do not change the loop above */ spello (SPELL_ANIMATE_DEAD, 175, 150, 3, POS_STANDING, TAR_OBJ_ROOM, FALSE, MAG_SUMMONS); spello (SPELL_ARMOR, 30, 15, 3, POS_FIGHTING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); spello (SPELL_BLESS, 35, 5, 3, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS); spello (SPELL_BLINDNESS, 35, 25, 1, POS_STANDING, TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_AFFECTS); spello (SPELL_CHARM, 75, 50, 2, POS_FIGHTING, TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL); spello (SPELL_CLONE, 200, 150, 5, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_SUMMONS); spello (SPELL_CONTROL_WEATHER, 75, 25, 5, POS_STANDING, TAR_IGNORE, FALSE, MAG_MANUAL); spello (SPELL_CREATE_FOOD, 30, 5, 4, POS_STANDING, TAR_IGNORE, FALSE, MAG_CREATIONS); spello (SPELL_CREATE_WATER, 30, 5, 4, POS_STANDING, TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL); spello (SPELL_CURE_BLIND, 30, 5, 2, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_UNAFFECTS); spello (SPELL_CURE_CRITIC, 30, 10, 2, POS_FIGHTING, TAR_CHAR_ROOM, FALSE, MAG_POINTS); spello (SPELL_CURE_LIGHT, 30, 10, 2, POS_FIGHTING, TAR_CHAR_ROOM, FALSE, MAG_POINTS); spello (SPELL_CURSE, 80, 50, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS); spello (SPELL_DETECT_ALIGN, 20, 10, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_DETECT_INVIS, 20, 10, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_DETECT_MAGIC, 20, 10, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_DETECT_POISON, 15, 5, 1, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL); spello (SPELL_EARTHQUAKE, 40, 25, 3, POS_FIGHTING, TAR_IGNORE, TRUE, MAG_AREAS); spello (SPELL_ENCHANT_WEAPON, 150, 100, 10, POS_STANDING, TAR_OBJ_INV | TAR_OBJ_EQUIP, FALSE, MAG_MANUAL); spello (SPELL_GROUP_ARMOR, 50, 30, 2, POS_STANDING, TAR_IGNORE, FALSE, MAG_GROUPS); spello (SPELL_GROUP_HEAL, 80, 60, 5, POS_STANDING, TAR_IGNORE, FALSE, MAG_GROUPS); spello (SPELL_HEAL, 60, 40, 3, POS_FIGHTING, TAR_CHAR_ROOM, FALSE, MAG_POINTS | MAG_AFFECTS | MAG_UNAFFECTS); spello (SPELL_INFRAVISION, 25, 10, 1, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_INVISIBLE, 35, 25, 1, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_AFFECTS | MAG_ALTER_OBJS); spello (SPELL_LOCATE_OBJECT, 25, 20, 1, POS_STANDING, TAR_OBJ_WORLD, FALSE, MAG_MANUAL); spello (SPELL_LOCATE_TARGET, 100, 20, 1, POS_STANDING, TAR_CHAR_WORLD, FALSE, MAG_MANUAL); spello (SPELL_POISON, 50, 20, 3, POS_STANDING, TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV, TRUE, MAG_AFFECTS | MAG_ALTER_OBJS); spello (SPELL_REMOVE_CURSE, 45, 25, 5, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV, FALSE, MAG_UNAFFECTS | MAG_ALTER_OBJS); spello (SPELL_SANCTUARY, 110, 85, 5, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); spello (SPELL_SLEEP, 40, 25, 5, POS_STANDING, TAR_CHAR_ROOM, TRUE, MAG_AFFECTS); spello (SPELL_STRENGTH, 35, 30, 1, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); spello (SPELL_SUMMON, 75, 50, 3, POS_STANDING, TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL); spello (SPELL_WORD_OF_RECALL, 20, 10, 2, POS_FIGHTING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_MANUAL); spello (SPELL_REMOVE_POISON, 40, 8, 4, POS_STANDING, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_UNAFFECTS | MAG_ALTER_OBJS); spello (SPELL_SENSE_LIFE, 20, 10, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_STONE_SKIN, 120, 60, 3, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_FEAR, 100, 50, 1, POS_FIGHTING, TAR_CHAR_ROOM | TAR_NOT_SELF, TRUE, MAG_MANUAL); spello (SPELL_RECHARGE, 150, 75, 1, POS_STANDING, TAR_CHAR_ROOM | TAR_NOT_SELF | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL); spello(SPELL_PORTAL, 170, 100, 5, POS_STANDING, TAR_CHAR_WORLD | TAR_NOT_SELF, FALSE, MAG_MANUAL); spello (SPELL_GROUP_STONE_SKIN, 240, 120, 2, POS_STANDING, TAR_IGNORE, FALSE, MAG_GROUPS); spello (SPELL_CONVERGENCE, 110, 85, 5, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); spello (SPELL_AUTUS, 140, 100, 5, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); spello (SPELL_RESIST_PORTAL, 200, 100, 2, POS_STANDING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello (SPELL_REGEN_MANA, 150, 150, 0, POS_FIGHTING, TAR_CHAR_ROOM | TAR_NOT_SELF, FALSE, MAG_POINTS); spello (SPELL_HOME, 80, 20, 1, POS_FIGHTING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_MANUAL); spello (SPELL_WORD_OF_RETREAT, 30, 20, 1, POS_FIGHTING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_MANUAL); spello (SPELL_WATERWALK, 200, 150, 1, POS_FIGHTING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS); spello(SPELL_REDIRECT_CHARGE, 200, 100, 5, POS_STANDING, TAR_CHAR_ROOM, FALSE, MAG_AFFECTS); /* NON-castable spells should appear here */ spello (SPELL_IDENTIFY, 0, 0, 0, 0, TAR_CHAR_ROOM | TAR_OBJ_INV | TAR_OBJ_ROOM, FALSE, MAG_MANUAL); /* * 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 the skill for other classes is set up in class.c. */ skillo (SKILL_BACKSTAB); skillo (SKILL_BASH); skillo (SKILL_HIDE); skillo (SKILL_KICK); skillo (SKILL_BERSERK); skillo (SKILL_PICK_LOCK); skillo (SKILL_RAM_DOOR); skillo (SKILL_PUNCH); skillo (SKILL_RESCUE); skillo (SKILL_SNEAK); skillo (SKILL_CAMOUFLAGE); skillo (SKILL_BLANKET); skillo (SKILL_STEAL); skillo (SKILL_TRACK); skillo (SKILL_FORAGE); skillo (SKILL_SCAN); skillo (SKILL_BREW); skillo (SKILL_FORGE); skillo (SKILL_SCRIBE); skillo (SKILL_SPEED); skillo (SKILL_MOUNT); skillo (SKILL_RIDING); skillo (SKILL_TAME); skillo (SKILL_SECOND_ATTACK); skillo (SKILL_THIRD_ATTACK); skillo (SKILL_LISTEN); skillo (SKILL_MEDITATE); skillo (SKILL_REPAIR); skillo (SKILL_TAN); skillo (SKILL_FILLET); skillo (SKILL_CARVE); skillo (SKILL_DODGE); skillo (SKILL_PARRY); skillo (SKILL_AVOID); skillo (SKILL_RIPOSTE); skillo (SKILL_CIRCLE); skillo (SKILL_TRIP); skillo (SKILL_TARGET); skillo (SKILL_DISARM); skillo (SKILL_CHAIN_FOOTING); skillo (SKILL_ADRENALINE); skillo (SKILL_BLOODLUST); skillo (SKILL_CARNALRAGE); }