*** /home/parsifal/dean/src/nh/uunet/include/extern.h Mon Apr 7 11:46:25 1997 --- include/extern.h Mon Apr 7 11:46:44 1997 *************** *** 44,49 **** --- 44,50 ---- E int NDECL(doapply); E int NDECL(dorub); E int NDECL(dojump); + E int FDECL(jump, (int)); E int NDECL(number_leashed); E void FDECL(o_unleash, (struct obj *)); E void FDECL(m_unleash, (struct monst *)); *************** *** 1654,1659 **** --- 1655,1661 ---- #endif E int FDECL(study_book, (struct obj *)); E int NDECL(docast); + E int FDECL(spell_skilltype, (int)); E int FDECL(spelleffects, (int,BOOLEAN_P)); E void NDECL(losespells); E int NDECL(dovspell); *************** *** 1959,1965 **** #ifdef WEAPON_SKILLS E int NDECL(enhance_weapon_skill); E void FDECL(unrestrict_weapon_skill, (int)); ! E void FDECL(use_skill, (int)); E void FDECL(add_weapon_skill, (int)); E void FDECL(lose_weapon_skill, (int)); E int FDECL(weapon_type, (struct obj *)); --- 1961,1967 ---- #ifdef WEAPON_SKILLS E int NDECL(enhance_weapon_skill); E void FDECL(unrestrict_weapon_skill, (int)); ! E void FDECL(use_skill, (int,int)); E void FDECL(add_weapon_skill, (int)); E void FDECL(lose_weapon_skill, (int)); E int FDECL(weapon_type, (struct obj *)); *************** *** 2060,2065 **** --- 2062,2068 ---- E void FDECL(cancel_monst, (struct monst *,struct obj *, BOOLEAN_P,BOOLEAN_P,BOOLEAN_P)); E void FDECL(weffects, (struct obj *)); + E int NDECL(spell_damage_bonus); E const char *FDECL(exclam, (int force)); E void FDECL(hit, (const char *,struct monst *,const char *)); E void FDECL(miss, (const char *,struct monst *)); *** /home/parsifal/dean/src/nh/uunet/include/spell.h Fri Aug 4 08:30:24 1995 --- include/spell.h Fri Apr 11 13:31:47 1997 *************** *** 6,14 **** #define SPELL_H struct spell { ! short sp_id; /* spell id (== object.otyp) */ ! xchar sp_lev; /* power level */ ! xchar sp_uses; /* uses left to spell */ }; /* levels of memory destruction with a scroll of amnesia */ --- 6,14 ---- #define SPELL_H struct spell { ! short sp_id; /* spell id (== object.otyp) */ ! xchar sp_lev; /* power level */ ! int sp_know; /* knowlege of spell */ }; /* levels of memory destruction with a scroll of amnesia */ *************** *** 15,18 **** --- 15,22 ---- #define ALL_MAP 0x1 #define ALL_SPELLS 0x2 + #define decrnknow(spell) spl_book[spell].sp_know-- + #define spellid(spell) spl_book[spell].sp_id + #define spellknow(spell) spl_book[spell].sp_know + #endif /* SPELL_H */ *** /home/parsifal/dean/src/nh/uunet/include/you.h Wed May 15 07:49:02 1996 --- include/you.h Fri Apr 11 12:38:01 1997 *************** *** 23,29 **** */ #ifdef WEAPON_SKILLS ! /* Weapon Skills - Stephen White */ #define P_DAGGER 0 #define P_KNIFE 1 #define P_AXE 2 --- 23,29 ---- */ #ifdef WEAPON_SKILLS ! /* Weapon Skills - Stephen White; Spell Skills added by Larry Stewart-Zerba */ #define P_DAGGER 0 #define P_KNIFE 1 #define P_AXE 2 *************** *** 53,65 **** #define P_BOOMERANG 26 #define P_WHIP 27 #define P_UNICORN_HORN 28 /* last weapon */ ! #define P_TWO_WEAPON_COMBAT 29 /* currently unused */ ! #define P_BARE_HANDED_COMBAT 30 #define P_MARTIAL_ARTS P_BARE_HANDED_COMBAT /* role distinguishes */ ! #define P_NUM_SKILLS 31 /* should always be the last entry */ #define P_NO_TYPE P_NUM_SKILLS #define P_LAST_WEAPON P_UNICORN_HORN /* * These are the standard weapon skill levels. It is important that --- 53,74 ---- #define P_BOOMERANG 26 #define P_WHIP 27 #define P_UNICORN_HORN 28 /* last weapon */ ! #define P_ATTACK_SPELL 29 ! #define P_HEALING_SPELL 30 ! #define P_DIVINATION_SPELL 31 ! #define P_ENCHANTMENT_SPELL 32 ! #define P_CLERIC_SPELL 33 ! #define P_ESCAPE_SPELL 34 ! #define P_MATTER_SPELL 35 ! #define P_CLASSLESS_SPELL 36 /* last spell */ ! #define P_TWO_WEAPON_COMBAT 37 /* currently unused */ ! #define P_BARE_HANDED_COMBAT 38 #define P_MARTIAL_ARTS P_BARE_HANDED_COMBAT /* role distinguishes */ ! #define P_NUM_SKILLS 39 /* should always be the last entry */ #define P_NO_TYPE P_NUM_SKILLS #define P_LAST_WEAPON P_UNICORN_HORN + #define P_LAST_SPELL P_CLASSLESS_SPELL /* * These are the standard weapon skill levels. It is important that *************** *** 93,101 **** /* categories whose names don't come from OBJ_NAME(objects[type]) */ #define PN_POLEARMS (-1) #define PN_SABER (-2) ! #define PN_TWO_WEAPONS (-3) ! #define PN_BARE_HANDED (-4) ! #define PN_MARTIAL_ARTS (-5) #define P_SKILL_LIMIT 60 /* max number of skill advancements */ --- 102,118 ---- /* categories whose names don't come from OBJ_NAME(objects[type]) */ #define PN_POLEARMS (-1) #define PN_SABER (-2) ! #define PN_ATTACK_SPELL (-3) ! #define PN_HEALING_SPELL (-4) ! #define PN_DIVINATION_SPELL (-5) ! #define PN_ENCHANTMENT_SPELL (-6) ! #define PN_CLERIC_SPELL (-7) ! #define PN_ESCAPE_SPELL (-8) ! #define PN_MATTER_SPELL (-9) ! #define PN_CLASSLESS_SPELL (-10) ! #define PN_TWO_WEAPONS (-11) ! #define PN_BARE_HANDED (-12) ! #define PN_MARTIAL_ARTS (-13) #define P_SKILL_LIMIT 60 /* max number of skill advancements */ *************** *** 292,297 **** --- 309,317 ---- #define LUCKMIN (-10) schar udaminc; schar uac; + uchar uspellprot; /* protection by SPE_PROTECTION */ + uchar usptime; /* #moves until uspellprot-- */ + uchar uspmtime; /* #moves between uspellprot-- */ int uhp,uhpmax; int uen, uenmax; /* magical energy - M. Stephenson */ int ugangr; /* if the gods are angry at you */ *** /home/parsifal/dean/src/nh/uunet/src/allmain.c Mon Jan 27 17:42:15 1997 --- src/allmain.c Sat Apr 12 15:28:41 1997 *************** *** 23,29 **** char ch; int abort_lev; #endif ! int moverate = 0; boolean didmove = 0; flags.moonphase = phase_of_the_moon(); --- 23,29 ---- char ch; int abort_lev; #endif ! int i, moverate = 0; boolean didmove = 0; flags.moonphase = phase_of_the_moon(); *************** *** 183,189 **** (Role_is('W') ? 3 : 4) / 6)))) || Energy_regeneration)) { u.uen += ! rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 10 + 1,1); if (u.uen > u.uenmax) u.uen = u.uenmax; flags.botl = 1; } --- 183,189 ---- (Role_is('W') ? 3 : 4) / 6)))) || Energy_regeneration)) { u.uen += ! rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1); if (u.uen > u.uenmax) u.uen = u.uenmax; flags.botl = 1; } *************** *** 223,228 **** --- 223,252 ---- moverate = 0; } } + + /* + * The time relative to the hero (a pass through move + * loop) causes all spell knowledge to be decremented. + * The hero's speed, rest status, conscious status etc. + * does not alter the lose of memory. (Try this for + * now, complicate it only as needed.) + */ + for (i=0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) + if (spellknow(i)) + decrnknow(i); + + /* Dissipate spell-based protection. */ + if (u.usptime) { + if (--u.usptime == 0 && u.uspellprot) { + u.usptime = u.uspmtime; + u.uspellprot--; + if (!Blind) + pline_The("golden haze around you %s.", + u.uspellprot ? "becomes less dense" : + "disappears"); + find_ac(); + } + } if(Searching && multi >= 0) (void) dosearch0(1); do_storms(); *** /home/parsifal/dean/src/nh/uunet/src/apply.c Mon Oct 21 21:10:20 1996 --- src/apply.c Sat Apr 5 08:40:22 1997 *************** *** 1107,1139 **** int dojump() { coord cc; struct monst *mtmp; ! if (nolimbs(uasmon) || slithy(uasmon)) { /* normally (nolimbs || slithy) implies !Jumping, but that isn't necessarily the case for knights */ You_cant("jump; you have no legs!"); return 0; ! } else if (!Jumping) { You_cant("jump very far."); return 0; } else if (u.uswallow) { pline("You've got to be kidding!"); return 0; } else if (u.uinwater) { pline("This calls for swimming, not jumping!"); return 0; } else if (u.ustuck) { You("cannot escape from %s!", mon_nam(u.ustuck)); return 0; } else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) { You("don't have enough traction to jump."); return 0; ! } else if (near_capacity() > UNENCUMBERED) { You("are carrying too much to jump!"); return 0; ! } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) { You("lack the strength to jump!"); return 0; } else if (Wounded_legs) { --- 1107,1163 ---- int dojump() { + /* Physical jump */ + return jump(0); + } + + int + jump(magic) + int magic; /* 0=Physical, otherwise skill level */ + { coord cc; struct monst *mtmp; ! if (!magic && (nolimbs(uasmon) || slithy(uasmon))) { /* normally (nolimbs || slithy) implies !Jumping, but that isn't necessarily the case for knights */ You_cant("jump; you have no legs!"); return 0; ! } else if (!magic && !Jumping) { You_cant("jump very far."); return 0; } else if (u.uswallow) { + if (magic) { + You("bounce around a little."); + return 1; + } pline("You've got to be kidding!"); return 0; } else if (u.uinwater) { + if (magic) { + You("swish around a little."); + return 1; + } pline("This calls for swimming, not jumping!"); return 0; } else if (u.ustuck) { + if (magic) { + You("writhe a little in the grasp of %s!", mon_nam(u.ustuck)); + return 1; + } You("cannot escape from %s!", mon_nam(u.ustuck)); return 0; } else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) { + if (magic) { + You("flail around a little."); + return 1; + } You("don't have enough traction to jump."); return 0; ! } else if (!magic && near_capacity() > UNENCUMBERED) { You("are carrying too much to jump!"); return 0; ! } else if (!magic && (u.uhunger <= 100 || ACURR(A_STR) < 6)) { You("lack the strength to jump!"); return 0; } else if (Wounded_legs) { *************** *** 1154,1163 **** cc.y = u.uy; getpos(&cc, TRUE, "the desired position"); if(cc.x == -10) return 0; /* user pressed esc */ ! if (!(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) { pline("Illegal move!"); return 0; ! } else if (distu(cc.x, cc.y) > 9) { pline("Too far!"); return 0; } else if (!cansee(cc.x, cc.y)) { --- 1178,1187 ---- cc.y = u.uy; getpos(&cc, TRUE, "the desired position"); if(cc.x == -10) return 0; /* user pressed esc */ ! if (!magic && !(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) { pline("Illegal move!"); return 0; ! } else if (distu(cc.x, cc.y) > (magic ? 6+magic*3 : 9)) { pline("Too far!"); return 0; } else if (!cansee(cc.x, cc.y)) { *** /home/parsifal/dean/src/nh/uunet/src/attrib.c Mon Jun 17 17:36:36 1996 --- src/attrib.c Sat Apr 5 08:25:53 1997 *************** *** 97,102 **** --- 97,106 ---- * a minimum strength of 6 since without one you can't teleport or cast * spells. --KAA */ + /* As the wizard has been updated (wizard patch 5 jun '96) there HD can be + * brought closer into line with AD&D. This forces wizards to use magic more + * and distance themselves from their attackers. --LSZ + */ const struct innate *abil; } a_attr = { {{ 7, 10, 10, 7, 7, 7 }}, /* Archeologist */ {{ 20, 20, 20, 10, 20, 10 }}, *************** *** 146,152 **** w_attr = { {{ 7, 10, 7, 7, 7, 7 }}, /* Wizard (magic-user) */ {{ 10, 30, 10, 20, 20, 10 }}, ! { A_NEUTRAL, 0 }, 12, 10, 12, 1, w_abil }, X_attr = { {{ 3, 3, 3, 3, 3, 3 }}, {{ 20, 15, 15, 15, 20, 15 }}, --- 150,156 ---- w_attr = { {{ 7, 10, 7, 7, 7, 7 }}, /* Wizard (magic-user) */ {{ 10, 30, 10, 20, 20, 10 }}, ! { A_NEUTRAL, 0 }, 12, 6, 12, 1, w_abil }, X_attr = { {{ 3, 3, 3, 3, 3, 3 }}, {{ 20, 15, 15, 15, 20, 15 }}, *** /home/parsifal/dean/src/nh/uunet/src/do_wear.c Mon Apr 7 11:46:26 1997 --- src/do_wear.c Fri Apr 11 18:32:34 1997 *************** *** 1309,1314 **** --- 1309,1315 ---- if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe; if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe; if (Protection & INTRINSIC) uac -= u.ublessed; + uac -= u.uspellprot; if(uac != u.uac){ u.uac = uac; flags.botl = 1; *** /home/parsifal/dean/src/nh/uunet/src/dokick.c Mon Jan 27 16:29:59 1997 --- src/dokick.c Sat Apr 12 15:06:29 1997 *************** *** 93,99 **** #ifdef WEAPON_SKILLS /* may bring up a dialog, so put this after all messages */ if (kick_skill != P_NO_TYPE) /* exercise proficiency */ ! use_skill(kick_skill); #endif } --- 93,99 ---- #ifdef WEAPON_SKILLS /* may bring up a dialog, so put this after all messages */ if (kick_skill != P_NO_TYPE) /* exercise proficiency */ ! use_skill(kick_skill, 1); #endif } *** /home/parsifal/dean/src/nh/uunet/src/objects.c Mon Jun 17 17:36:24 1996 --- src/objects.c Sat Apr 5 08:25:54 1997 *************** *** 734,756 **** OBJ(name,desc), BITS(0,0,0,0,mgc,0,0,0,0,0,dir,0,PAPER), 0, \ SPBOOK_CLASS, prob, delay, \ 50, level*100, 0, 0, 0, level, 20, color ) ! SPELL("dig", "parchment", 22, 6, 5, 1, RAY, HI_PAPER), ! SPELL("magic missile", "vellum", 45, 3, 2, 1, RAY, HI_PAPER), ! SPELL("fireball", "ragged", 20, 6, 4, 1, RAY, HI_PAPER), ! SPELL("cone of cold", "dog eared", 10, 8, 5, 1, RAY, HI_PAPER), SPELL("sleep", "mottled", 50, 1, 1, 1, RAY, HI_PAPER), SPELL("finger of death", "stained", 5, 10, 7, 1, RAY, HI_PAPER), SPELL("light", "cloth", 45, 1, 1, 1, NODIR, HI_CLOTH), SPELL("detect monsters", "leather", 45, 1, 1, 1, NODIR, HI_LEATHER), SPELL("healing", "white", 40, 2, 1, 1, IMMEDIATE, CLR_WHITE), ! SPELL("knock", "pink", 36, 1, 1, 1, IMMEDIATE, CLR_BRIGHT_MAGENTA), SPELL("force bolt", "red", 35, 2, 1, 1, IMMEDIATE, CLR_RED), ! SPELL("confuse monster", "orange", 37, 2, 2, 1, IMMEDIATE, CLR_ORANGE), SPELL("cure blindness", "yellow", 27, 2, 2, 1, IMMEDIATE, CLR_YELLOW), ! SPELL("slow monster", "light green", 37, 2, 2, 1, IMMEDIATE, CLR_BRIGHT_GREEN), ! SPELL("wizard lock", "dark green", 35, 3, 2, 1, IMMEDIATE, CLR_GREEN), ! SPELL("create monster", "turquoise", 37, 3, 2, 1, NODIR, CLR_BRIGHT_CYAN), ! SPELL("detect food", "cyan", 37, 3, 2, 1, NODIR, CLR_CYAN), SPELL("cause fear", "light blue", 25, 3, 3, 1, NODIR, CLR_BRIGHT_BLUE), SPELL("clairvoyance", "dark blue", 15, 3, 3, 1, NODIR, CLR_BLUE), SPELL("cure sickness", "indigo", 32, 3, 3, 1, NODIR, CLR_BLUE), --- 734,756 ---- OBJ(name,desc), BITS(0,0,0,0,mgc,0,0,0,0,0,dir,0,PAPER), 0, \ SPBOOK_CLASS, prob, delay, \ 50, level*100, 0, 0, 0, level, 20, color ) ! SPELL("dig", "parchment", 20, 6, 5, 1, RAY, HI_PAPER), ! SPELL("magic missile", "vellum", 45, 2, 2, 1, RAY, HI_PAPER), ! SPELL("fireball", "ragged", 20, 4, 4, 1, RAY, HI_PAPER), ! SPELL("cone of cold", "dog eared", 10, 7, 4, 1, RAY, HI_PAPER), SPELL("sleep", "mottled", 50, 1, 1, 1, RAY, HI_PAPER), SPELL("finger of death", "stained", 5, 10, 7, 1, RAY, HI_PAPER), SPELL("light", "cloth", 45, 1, 1, 1, NODIR, HI_CLOTH), SPELL("detect monsters", "leather", 45, 1, 1, 1, NODIR, HI_LEATHER), SPELL("healing", "white", 40, 2, 1, 1, IMMEDIATE, CLR_WHITE), ! SPELL("knock", "pink", 35, 1, 1, 1, IMMEDIATE, CLR_BRIGHT_MAGENTA), SPELL("force bolt", "red", 35, 2, 1, 1, IMMEDIATE, CLR_RED), ! SPELL("confuse monster", "orange", 30, 2, 2, 1, IMMEDIATE, CLR_ORANGE), SPELL("cure blindness", "yellow", 27, 2, 2, 1, IMMEDIATE, CLR_YELLOW), ! SPELL("slow monster", "light green", 30, 2, 2, 1, IMMEDIATE, CLR_BRIGHT_GREEN), ! SPELL("wizard lock", "dark green", 30, 3, 2, 1, IMMEDIATE, CLR_GREEN), ! SPELL("create monster", "turquoise", 35, 3, 2, 1, NODIR, CLR_BRIGHT_CYAN), ! SPELL("detect food", "cyan", 36, 3, 2, 1, NODIR, CLR_CYAN), SPELL("cause fear", "light blue", 25, 3, 3, 1, NODIR, CLR_BRIGHT_BLUE), SPELL("clairvoyance", "dark blue", 15, 3, 3, 1, NODIR, CLR_BLUE), SPELL("cure sickness", "indigo", 32, 3, 3, 1, NODIR, CLR_BLUE), *************** *** 758,777 **** SPELL("haste self", "purple", 33, 4, 3, 1, NODIR, CLR_MAGENTA), SPELL("detect unseen", "violet", 20, 4, 3, 1, NODIR, CLR_MAGENTA), SPELL("levitation", "tan", 20, 4, 4, 1, NODIR, CLR_BROWN), ! SPELL("extra healing", "plaid", 35, 5, 3, 1, IMMEDIATE, CLR_GREEN), SPELL("restore ability", "light brown", 25, 5, 4, 1, NODIR, CLR_BROWN), ! SPELL("invisibility", "dark brown", 32, 5, 4, 1, NODIR, CLR_BROWN), SPELL("detect treasure", "gray", 25, 5, 4, 1, NODIR, CLR_GRAY), ! SPELL("remove curse", "wrinkled", 25, 5, 5, 1, NODIR, HI_PAPER), SPELL("magic mapping", "dusty", 18, 7, 5, 1, NODIR, HI_PAPER), ! SPELL("identify", "bronze", 25, 8, 5, 1, NODIR, HI_COPPER), SPELL("turn undead", "copper", 17, 8, 6, 1, IMMEDIATE, HI_COPPER), SPELL("polymorph", "silver", 10, 8, 6, 1, IMMEDIATE, HI_SILVER), SPELL("teleport away", "gold", 15, 6, 6, 1, IMMEDIATE, HI_GOLD), SPELL("create familiar", "glittering", 10, 7, 6, 1, NODIR, CLR_WHITE), SPELL("cancellation", "shining", 15, 8, 7, 1, IMMEDIATE, CLR_WHITE), ! SPELL((char *)0, "dull", 0, 0, 0, 1, 0, HI_PAPER), ! SPELL((char *)0, "thin", 0, 0, 0, 1, 0, HI_PAPER), SPELL((char *)0, "thick", 0, 0, 0, 1, 0, HI_PAPER), /* blank spellbook must come last because it retains its description */ SPELL("blank paper", "plain", 20, 0, 0, 0, 0, HI_PAPER), --- 758,777 ---- SPELL("haste self", "purple", 33, 4, 3, 1, NODIR, CLR_MAGENTA), SPELL("detect unseen", "violet", 20, 4, 3, 1, NODIR, CLR_MAGENTA), SPELL("levitation", "tan", 20, 4, 4, 1, NODIR, CLR_BROWN), ! SPELL("extra healing", "plaid", 27, 5, 3, 1, IMMEDIATE, CLR_GREEN), SPELL("restore ability", "light brown", 25, 5, 4, 1, NODIR, CLR_BROWN), ! SPELL("invisibility", "dark brown", 25, 5, 4, 1, NODIR, CLR_BROWN), SPELL("detect treasure", "gray", 25, 5, 4, 1, NODIR, CLR_GRAY), ! SPELL("remove curse", "wrinkled", 25, 5, 3, 1, NODIR, HI_PAPER), SPELL("magic mapping", "dusty", 18, 7, 5, 1, NODIR, HI_PAPER), ! SPELL("identify", "bronze", 20, 6, 3, 1, NODIR, HI_COPPER), SPELL("turn undead", "copper", 17, 8, 6, 1, IMMEDIATE, HI_COPPER), SPELL("polymorph", "silver", 10, 8, 6, 1, IMMEDIATE, HI_SILVER), SPELL("teleport away", "gold", 15, 6, 6, 1, IMMEDIATE, HI_GOLD), SPELL("create familiar", "glittering", 10, 7, 6, 1, NODIR, CLR_WHITE), SPELL("cancellation", "shining", 15, 8, 7, 1, IMMEDIATE, CLR_WHITE), ! SPELL("protection", "dull", 20, 3, 1, 1, NODIR, HI_PAPER), ! SPELL("jumping", "thin", 25, 3, 1, 1, IMMEDIATE, HI_PAPER), SPELL((char *)0, "thick", 0, 0, 0, 1, 0, HI_PAPER), /* blank spellbook must come last because it retains its description */ SPELL("blank paper", "plain", 20, 0, 0, 0, 0, HI_PAPER), *** /home/parsifal/dean/src/nh/uunet/src/pray.c Sat Apr 5 00:06:22 1997 --- src/pray.c Sat Apr 12 02:15:43 1997 *************** *** 719,735 **** obj->dknown = TRUE; } else if (!exist_artifact(LONG_SWORD, artiname(ART_VORPAL_BLADE))) { ! obj = mksobj(LONG_SWORD, FALSE, FALSE); ! obj = oname(obj, artiname(ART_VORPAL_BLADE)); pline("%s %s %s your %s!", Blind ? Something : "A", ! Blind ? "lands" : "sword appears", Levitation ? "beneath" : "at", makeplural(body_part(FOOT))); - obj->spe = 1; dropy(obj); - #ifdef WEAPON_SKILLS - unrestrict_weapon_skill(P_LONG_SWORD); - #endif /* WEAPON_SKILLS */ } break; case A_CHAOTIC: --- 719,742 ---- obj->dknown = TRUE; } else if (!exist_artifact(LONG_SWORD, artiname(ART_VORPAL_BLADE))) { ! boolean is_wiz = Role_is('W'); ! ! if (is_wiz) { ! obj = mksobj(SPE_FINGER_OF_DEATH,TRUE,FALSE); ! } else { ! obj = mksobj(LONG_SWORD, FALSE, FALSE); ! obj = oname(obj, artiname(ART_VORPAL_BLADE)); ! obj->spe = 1; ! #ifdef WEAPON_SKILLS ! unrestrict_weapon_skill(P_LONG_SWORD); ! #endif /* WEAPON_SKILLS */ ! } pline("%s %s %s your %s!", Blind ? Something : "A", ! Blind ? "lands" : ! is_wiz ? "spellbook appears" : "sword appears", Levitation ? "beneath" : "at", makeplural(body_part(FOOT))); dropy(obj); } break; case A_CHAOTIC: *************** *** 780,785 **** --- 787,795 ---- obj->oerodeproof = TRUE; obj->bknown = obj->rknown = TRUE; if (obj->spe < 1) obj->spe = 1; + } else if (obj && (obj->oclass == SPBOOK_CLASS)) { + obj->bknown = obj->rknown = TRUE; + bless(obj); } else /* opportunity knocked, but there was nobody home... */ You_feel("unworthy."); break; *** /home/parsifal/dean/src/nh/uunet/src/spell.c Tue Aug 13 12:27:25 1996 --- src/spell.c Mon Apr 14 22:51:38 1997 *************** *** 7,16 **** static NEARDATA schar delay; /* moves left for this spell */ static NEARDATA struct obj *book; /* last/current book being xscribed */ ! #define spelluses(spell) spl_book[spell].sp_uses ! #define decrnuses(spell) spl_book[spell].sp_uses-- #define spellev(spell) spl_book[spell].sp_lev - #define spellid(spell) spl_book[spell].sp_id #define spellname(spell) OBJ_NAME(objects[spellid(spell)]) #define spellet(spell) \ ((char)((spell < 26) ? ('a' + spell) : ('A' + spell - 26))) --- 7,17 ---- static NEARDATA schar delay; /* moves left for this spell */ static NEARDATA struct obj *book; /* last/current book being xscribed */ ! #define KEEN 5000 ! #define MAX_SPELL_STUDY 3 ! #define incrnknow(spell) spl_book[spell].sp_know = KEEN ! #define spellev(spell) spl_book[spell].sp_lev #define spellname(spell) OBJ_NAME(objects[spellid(spell)]) #define spellet(spell) \ ((char)((spell < 26) ? ('a' + spell) : ('A' + spell - 26))) *************** *** 21,26 **** --- 22,29 ---- static boolean FDECL(getspell, (int *)); static boolean FDECL(dospellmenu, (int, int *)); static int FDECL(percent_success, (int)); + static int NDECL(throwspell); + static int FDECL(isqrt, (int)); /* The cl_sptmp table lists the class-specific values for tuning * percent_success(). *************** *** 284,299 **** for (i = 0; i < MAXSPELL; i++) { if (spellid(i) == booktype) { ! if (book->spestudied >= rnd(30 - spellev(i))) { pline("This spellbook is too faint to be read anymore."); book->otyp = booktype = SPE_BLANK_PAPER; ! } else if (spelluses(i) < 20 - spellev(i)) { ! Your("knowledge of that spell is keener."); ! spl_book[i].sp_uses += 10 - spellev(i); book->spestudied++; ! exercise(A_WIS, TRUE); /* extra study */ ! } else ! You("know that spell quite well already."); /* make book become known even when spell is already known, in case amnesia made you forget the book */ makeknown((int)booktype); --- 287,302 ---- for (i = 0; i < MAXSPELL; i++) { if (spellid(i) == booktype) { ! if (book->spestudied > MAX_SPELL_STUDY) { pline("This spellbook is too faint to be read anymore."); book->otyp = booktype = SPE_BLANK_PAPER; ! } else if (spellknow(i) <= 1000) { ! Your("knowledge of that spell is keener"); ! incrnknow(i); book->spestudied++; ! exercise(A_WIS,TRUE); /* extra study */ ! } else /* 1000 < spellknow(i) <= 5000 */ ! You("know that spell quite well already."); /* make book become known even when spell is already known, in case amnesia made you forget the book */ makeknown((int)booktype); *************** *** 301,308 **** } else if (spellid(i) == NO_SPELL) { spl_book[i].sp_id = booktype; spl_book[i].sp_lev = objects[booktype].oc_level; ! spl_book[i].sp_uses = 30 - spellev(i); book->spestudied++; You("add the spell to your repertoire."); makeknown((int)booktype); break; --- 304,312 ---- } else if (spellid(i) == NO_SPELL) { spl_book[i].sp_id = booktype; spl_book[i].sp_lev = objects[booktype].oc_level; ! incrnknow(i); book->spestudied++; + You("have keen knowledge of the spell."); You("add the spell to your repertoire."); makeknown((int)booktype); break; *************** *** 324,329 **** --- 328,334 ---- { register int booktype = spellbook->otyp; register boolean confused = (Confusion != 0); + boolean too_hard = FALSE; if (delay && spellbook == book) You("continue your efforts to memorize the spell."); *************** *** 342,347 **** --- 347,354 ---- case SPE_LIGHT: case SPE_SLEEP: case SPE_KNOCK: + case SPE_PROTECTION: + case SPE_JUMPING: /* level 2 spells */ case SPE_MAGIC_MISSILE: case SPE_CONFUSE_MONSTER: *************** *** 358,365 **** case SPE_CURE_SICKNESS: case SPE_DETECT_UNSEEN: case SPE_EXTRA_HEALING: - case SPE_CHARM_MONSTER: case SPE_CLAIRVOYANCE: /* level 4 spells */ case SPE_LEVITATION: case SPE_RESTORE_ABILITY: --- 365,373 ---- case SPE_CURE_SICKNESS: case SPE_DETECT_UNSEEN: case SPE_EXTRA_HEALING: case SPE_CLAIRVOYANCE: + case SPE_REMOVE_CURSE: + case SPE_IDENTIFY: /* level 4 spells */ case SPE_LEVITATION: case SPE_RESTORE_ABILITY: *************** *** 366,379 **** case SPE_INVISIBILITY: case SPE_FIREBALL: case SPE_DETECT_TREASURE: delay = -(objects[booktype].oc_level - 1) * objects[booktype].oc_delay; break; /* level 5 spells */ - case SPE_REMOVE_CURSE: case SPE_MAGIC_MAPPING: - case SPE_CONE_OF_COLD: - case SPE_IDENTIFY: case SPE_DIG: /* level 6 spells */ case SPE_TURN_UNDEAD: case SPE_POLYMORPH: --- 374,386 ---- case SPE_INVISIBILITY: case SPE_FIREBALL: case SPE_DETECT_TREASURE: + case SPE_CONE_OF_COLD: delay = -(objects[booktype].oc_level - 1) * objects[booktype].oc_delay; break; /* level 5 spells */ case SPE_MAGIC_MAPPING: case SPE_DIG: + case SPE_CHARM_MONSTER: /* level 6 spells */ case SPE_TURN_UNDEAD: case SPE_POLYMORPH: *************** *** 397,422 **** #ifndef NO_SIGNAL spellbook->in_use = TRUE; #endif ! if(!spellbook->blessed && ! spellbook->otyp != SPE_BOOK_OF_THE_DEAD && ! (spellbook->cursed || ! rn2(20) > (ACURR(A_INT) + 4 + u.ulevel/2 ! - 2*objects[booktype].oc_level))) { ! cursed_book(objects[booktype].oc_level); ! nomul(delay); /* study time */ ! delay = 0; ! if(!rn2(3)) { ! pline_The("spellbook crumbles to dust!"); ! if (!objects[spellbook->otyp].oc_name_known && ! !objects[spellbook->otyp].oc_uname) ! docall(spellbook); ! useup(spellbook); ! } #ifndef NO_SIGNAL ! else ! spellbook->in_use = FALSE; #endif ! return(1); } else if (confused) { if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) { --- 404,447 ---- #ifndef NO_SIGNAL spellbook->in_use = TRUE; #endif ! if (!spellbook->blessed && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) { ! if (spellbook->cursed) { ! too_hard = TRUE; ! } else { ! /* uncursed - chance to fail */ ! int read_ability = ACURR(A_INT) + 4 + u.ulevel/2 ! - 2*objects[booktype].oc_level; ! /* only wizards know if a spell is to difficult */ ! if (Role_is('W') && read_ability < 20) { ! char qbuf[QBUFSZ]; ! Sprintf(qbuf, ! "This spellbook is %sdifficult to comprehend. Continue?", ! (read_ability < 12 ? "very " : "")); ! if (ynq(qbuf) != 'y') return(1); ! } ! /* its up to random luck now */ ! if (rn2(20) > read_ability) { ! too_hard = TRUE; ! } ! } ! } ! ! if (too_hard) { ! cursed_book(objects[booktype].oc_level); ! nomul(delay); /* study time */ ! delay = 0; ! if(!rn2(3)) { ! pline_The("spellbook crumbles to dust!"); ! if (!objects[spellbook->otyp].oc_name_known && ! !objects[spellbook->otyp].oc_uname) ! docall(spellbook); ! useup(spellbook); ! } #ifndef NO_SIGNAL ! else ! spellbook->in_use = FALSE; #endif ! return(1); } else if (confused) { if (!rn2(3) && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) { *************** *** 515,552 **** return 0; } int spelleffects(spell, atme) int spell; boolean atme; { ! int energy, damage, chance; boolean confused = (Confusion != 0); struct obj *pseudo; ! /* note that trying to cast it decrements the # of uses, */ ! /* even if the mage does not have enough food/energy to use */ ! /* the spell */ ! switch (spelluses(spell)) { ! case 0: ! pline ("Curdled magical energy twists through you..."); ! pline ("...you have overloaded and burned out this spell."); ! make_confused((long)spellev(spell) * 3, FALSE); ! return(0); ! case 1: ! case 2: ! case 3: ! Your("nerves tingle warningly."); ! break; ! case 4: ! case 5: ! case 6: ! pline ("This spell is starting to be over-used."); ! break; ! default: ! break; } - decrnuses(spell); energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */ if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) { --- 540,710 ---- return 0; } + static char* + spelltypemnemonic(int skill) + { + switch (skill) { + case P_ATTACK_SPELL: + return "atta"; + case P_HEALING_SPELL: + return "heal"; + case P_DIVINATION_SPELL: + return "divi"; + case P_ENCHANTMENT_SPELL: + return "ench"; + case P_CLERIC_SPELL: + return "cler"; + case P_ESCAPE_SPELL: + return "esca"; + case P_MATTER_SPELL: + return "matt"; + default: + impossible("Unknown spell skill, %d;", skill); + return ""; + } + } + int + spell_skilltype(booktype) + int booktype; + { + switch (booktype) { + case SPE_FORCE_BOLT: + case SPE_MAGIC_MISSILE: + case SPE_FIREBALL: + case SPE_CONE_OF_COLD: + case SPE_FINGER_OF_DEATH: + return P_ATTACK_SPELL; + case SPE_HEALING: + case SPE_CURE_BLINDNESS: + case SPE_CURE_SICKNESS: + case SPE_EXTRA_HEALING: + case SPE_RESTORE_ABILITY: + return P_HEALING_SPELL; + case SPE_LIGHT: + case SPE_DETECT_MONSTERS: + case SPE_IDENTIFY: + case SPE_DETECT_FOOD: + case SPE_DETECT_UNSEEN: + case SPE_CLAIRVOYANCE: + case SPE_DETECT_TREASURE: + case SPE_MAGIC_MAPPING: + return P_DIVINATION_SPELL; + case SPE_SLEEP: + case SPE_CONFUSE_MONSTER: + case SPE_SLOW_MONSTER: + case SPE_CAUSE_FEAR: + case SPE_CHARM_MONSTER: + return P_ENCHANTMENT_SPELL; + case SPE_PROTECTION: + case SPE_CREATE_MONSTER: + case SPE_REMOVE_CURSE: + case SPE_TURN_UNDEAD: + case SPE_CREATE_FAMILIAR: + return P_CLERIC_SPELL; + case SPE_JUMPING: + case SPE_HASTE_SELF: + case SPE_INVISIBILITY: + case SPE_LEVITATION: + case SPE_TELEPORT_AWAY: + return P_ESCAPE_SPELL; + case SPE_KNOCK: + case SPE_WIZARD_LOCK: + case SPE_DIG: + case SPE_POLYMORPH: + case SPE_CANCELLATION: + return P_MATTER_SPELL; + case SPE_BLANK_PAPER: + case SPE_BOOK_OF_THE_DEAD: + return P_CLASSLESS_SPELL; + default: + impossible("Unknown spellbook, %d;", booktype); + return P_NO_TYPE; + } + } + + static void + cast_protection() + { + int loglev=0; + int l=u.ulevel; + int natac=u.uac-u.uspellprot; + int gain; + + /* loglev=log2(u.ulevel)+1 (1..5) */ + while (l) { + loglev++; + l=l/2; + } + + /* The more u.uspellprot you already have, the less you get, + * and the better your natural ac, the less you get. + * + * LEVEL AC SPELLPROT from sucessive SPE_PROTECTION casts + * 1 10 0, 1, 2, 3, 4 + * 1 0 0, 1, 2, 3 + * 1 -10 0, 1, 2 + * 2-3 10 0, 2, 4, 5, 6, 7, 8 + * 2-3 0 0, 2, 4, 5, 6 + * 2-3 -10 0, 2, 3, 4 + * 4-7 10 0, 3, 6, 8, 9, 10, 11, 12 + * 4-7 0 0, 3, 5, 7, 8, 9 + * 4-7 -10 0, 3, 5, 6 + * 7-15 -10 0, 3, 5, 6 + * 8-15 10 0, 4, 7, 10, 12, 13, 14, 15, 16 + * 8-15 0 0, 4, 7, 9, 10, 11, 12 + * 8-15 -10 0, 4, 6, 7, 8 + * 16-30 10 0, 5, 9, 12, 14, 16, 17, 18, 19, 20 + * 16-30 0 0, 5, 9, 11, 13, 14, 15 + * 16-30 -10 0, 5, 8, 9, 10 + */ + gain = max(0,loglev-u.uspellprot/(4-min(3,(10-natac)/10))); + + if (gain > 0) { + if (!Blind) { + if (u.uspellprot) { + pline_The("golden haze around you becomes more dense."); + } else { + pline_The("%s around you begins to shimmer with a golden haze.", + (Underwater || Is_waterlevel(&u.uz)) ? "water" : "air"); + } + } + u.uspellprot += gain; + u.uspmtime = + P_SKILL(spell_skilltype(SPE_PROTECTION)) == P_EXPERT ? 20 : 10; + if (!u.usptime) + u.usptime = u.uspmtime; + find_ac(); + } else { + Your("skin feels warm for a moment."); + } + } + + int spelleffects(spell, atme) int spell; boolean atme; { ! int energy, damage, chance, n, intell; ! int skill, class_skill; boolean confused = (Confusion != 0); struct obj *pseudo; + coord cc; ! /* ! * Spell casting no longer effects knowledge of the spell. A ! * decrement of spell knowledge is done every turn. ! */ ! if (spellknow(spell)<=0) { ! Your("knowledge of this spell is twisted."); ! pline("It invokes nightmarish images in your mind..."); ! make_confused((long)spellev(spell) * 3, FALSE); ! return(0); ! } else if (spellknow(spell)<=100) { ! You("strain to recall the spell."); ! } else if (spellknow(spell)<=1000) { ! Your("knowledge of this spell is growing faint"); } energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */ if (u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) { *************** *** 563,569 **** return (0); } - if (u.uhave.amulet) { You_feel("the amulet draining your energy away."); energy += rnd(2*energy); --- 721,726 ---- *************** *** 583,588 **** --- 740,765 ---- */ if (hungr > u.uhunger-3) hungr = u.uhunger-3; + /* If hero is a wizard, their current intelligence + * (bonuses + temporary + current) + * effects hunger reduction in casting a spell. + * 1. int = 17-18 no reduction + * 2. int = 16 1/4 hungr + * 3. int = 15 1/2 hungr + * 4. int = 1-14 normal reduction + * The reason for this is: + * a) Intelligence effects the amount of exertion + * in thinking. + * b) Wizards have spent their life at magic and + * understand quite well how to casts spells. + */ + intell = acurr(A_INT); + switch (intell) { + case 18: + case 17: hungr = 0; break; + case 16: hungr /= 4; break; + case 15: hungr /= 2; break; + } morehungry(hungr); } } *************** *** 598,610 **** u.uen -= energy; flags.botl = 1; exercise(A_WIS, TRUE); ! /* pseudo is a temporary "false" object containing the spell stats. */ pseudo = mksobj(spellid(spell), FALSE, FALSE); pseudo->blessed = pseudo->cursed = 0; pseudo->quan = 20L; /* do not let useup get it */ switch(pseudo->otyp) { ! /* These spells are all duplicates of wand effects */ case SPE_FORCE_BOLT: case SPE_SLEEP: case SPE_MAGIC_MISSILE: --- 775,832 ---- u.uen -= energy; flags.botl = 1; exercise(A_WIS, TRUE); ! /* pseudo is a temporary "false" object containing the spell stats */ pseudo = mksobj(spellid(spell), FALSE, FALSE); pseudo->blessed = pseudo->cursed = 0; pseudo->quan = 20L; /* do not let useup get it */ + /* + * Find the skill the hero has in a spell type category. + * See spell_skilltype for categories. + */ + skill = spell_skilltype(pseudo->otyp); + class_skill = P_SKILL(skill); + switch(pseudo->otyp) { + /* + * At first these act as expected. As the character increases in + * experience the spell increases in its ability. Initially the + * spells have their expected levels of damage. When the hero level + * reaches three times the level of the spell the spell does special + * damage. This special damage is indicated before each spell. Note + * even when the hero reaches three times the level of the spell she + * still has the choice of casting either spell. Also the new level + * of spell has an increase cost in casting it. + */ + case SPE_CONE_OF_COLD: + case SPE_FIREBALL: + if (class_skill >= P_SKILLED) { + if (throwspell()) { + cc.x=u.dx;cc.y=u.dy; + n=rnd(8)+1; + while(n--) { + if(!u.dx && !u.dy && !u.dz) { + if ((damage = zapyourself(pseudo, TRUE)) != 0) + losehp(damage, + self_pronoun("zapped %sself with a spell", + "him"), + NO_KILLER_PREFIX); + } else { + explode(u.dx, u.dy, + pseudo->otyp - SPE_MAGIC_MISSILE + 10, + u.ulevel/2 + 1 + spell_damage_bonus(), 0); + } + u.dx = cc.x+rnd(3)-2; u.dy = cc.y+rnd(3)-2; + if (!cansee(u.dx,u.dy) || IS_STWALL(levl[u.dx][u.dy].typ)) { + /* Spell is reflected back to center */ + u.dx = cc.x; + u.dy = cc.y; + } + } + } + break; + } /* else fall through... */ ! /* these spells are all duplicates of wand effects */ case SPE_FORCE_BOLT: case SPE_SLEEP: case SPE_MAGIC_MISSILE: *************** *** 611,618 **** case SPE_KNOCK: case SPE_SLOW_MONSTER: case SPE_WIZARD_LOCK: - case SPE_FIREBALL: - case SPE_CONE_OF_COLD: case SPE_DIG: case SPE_TURN_UNDEAD: case SPE_POLYMORPH: --- 833,838 ---- *************** *** 635,651 **** } else weffects(pseudo); } else weffects(pseudo); break; ! /* These are all duplicates of scroll effects */ case SPE_CONFUSE_MONSTER: case SPE_DETECT_FOOD: case SPE_CAUSE_FEAR: case SPE_CHARM_MONSTER: - case SPE_REMOVE_CURSE: case SPE_MAGIC_MAPPING: case SPE_CREATE_MONSTER: case SPE_IDENTIFY: (void) seffects(pseudo); break; case SPE_HASTE_SELF: case SPE_DETECT_TREASURE: case SPE_DETECT_MONSTERS: --- 855,881 ---- } else weffects(pseudo); } else weffects(pseudo); break; ! ! /* these are all duplicates of scroll effects */ ! case SPE_REMOVE_CURSE: ! /* ! * When skilled enough the hero's spell is equivalent ! * to a blessed scroll. ! */ ! if (class_skill >= P_SKILLED) ! pseudo->blessed=1; ! /* fall through */ case SPE_CONFUSE_MONSTER: case SPE_DETECT_FOOD: case SPE_CAUSE_FEAR: case SPE_CHARM_MONSTER: case SPE_MAGIC_MAPPING: case SPE_CREATE_MONSTER: case SPE_IDENTIFY: (void) seffects(pseudo); break; + + /* these are all duplicates of potion effects */ case SPE_HASTE_SELF: case SPE_DETECT_TREASURE: case SPE_DETECT_MONSTERS: *************** *** 654,659 **** --- 884,890 ---- case SPE_INVISIBILITY: (void) peffects(pseudo); break; + case SPE_CURE_BLINDNESS: healup(0, 0, FALSE, TRUE); break; *************** *** 672,686 **** --- 903,966 ---- You("sense a pointy hat on top of your %s.", body_part(HEAD)); break; + case SPE_PROTECTION: + cast_protection(); + break; + case SPE_JUMPING: + if (!jump(class_skill)) + pline("Nothing happens."); + break; default: impossible("Unknown spell %d attempted.", spell); obfree(pseudo, (struct obj *)0); return(0); } + + /* gain skill for successful cast */ + if (class_skill != P_ISRESTRICTED && class_skill < P_EXPERT) + use_skill(skill, spellev(spell)); + obfree(pseudo, (struct obj *)0); /* now, get rid of it */ return(1); } + /* Choose location where spell takes effect. */ + static int + throwspell() + { + coord cc; + + if (u.uinwater) { + pline("You're joking! In this weather?"); return 0; + } else if (Is_waterlevel(&u.uz)) { + You("better wait for the sun to come out."); return 0; + } + + pline("Where do you want to cast the spell?"); + cc.x = u.ux; + cc.y = u.uy; + getpos(&cc, TRUE, "the desired position"); + if(cc.x == -10) return 0; /* user pressed esc */ + /* The number of moves from hero to where the spell drops.*/ + if (distmin(u.ux, u.uy, cc.x, cc.y) > 10) { + pline("The spell dissipates over the distance!"); + return 0; + } else if (u.uswallow) { + pline("The spell is cut short!"); + exercise(A_WIS, FALSE); /* What were you THINKING! */ + u.dx = 0; + u.dy = 0; + return 1; + } else if (!cansee(cc.x, cc.y) || IS_STWALL(levl[cc.x][cc.y].typ)) { + Your("mind fails to lock onto that location!"); + return 0; + } else { + u.dx=cc.x; + u.dy=cc.y; + return 1; + } + } + void losespells() { *************** *** 736,747 **** * To do it right would require that we implement columns * in the window-ports (say via a tab character). */ ! Sprintf(buf, "%-20s Level Fail", "Name"); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) { ! Sprintf(buf, "%-20s %2d%s %3d%%", spellname(i), spellev(i), ! spelluses(i) ? " " : "*", 100 - percent_success(i)); any.a_int = i+1; /* must be non-zero */ add_menu(tmpwin, NO_GLYPH, &any, --- 1016,1029 ---- * To do it right would require that we implement columns * in the window-ports (say via a tab character). */ ! Sprintf(buf, "%-20s Level Class Fail", "Name"); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) { ! Sprintf(buf, "%-20s %2d%s %-6s %3d%%", spellname(i), spellev(i), ! spellknow(i) ? " " : "*", ! spelltypemnemonic(spell_skilltype(spellid(i))), ! 100 - percent_success(i)); any.a_int = i+1; /* must be non-zero */ add_menu(tmpwin, NO_GLYPH, &any, *************** *** 760,766 **** --- 1042,1063 ---- return FALSE; } + /* Integer square root function without using floating point. */ static int + isqrt(val) + int val; + { + int rt = 0; + int odd = 1; + while(val >= odd) { + val = val-odd; + odd = odd+2; + rt = rt + 1; + } + return rt; + } + + static int percent_success(spell) int spell; { *************** *** 767,775 **** /* Intrinsic and learned ability are combined to calculate * the probability of player's success at cast a given spell. */ - int i, chance, splcaster, special, statused; int difficulty; /* Calculate intrinsic ability (splcaster) */ --- 1064,1072 ---- /* Intrinsic and learned ability are combined to calculate * the probability of player's success at cast a given spell. */ int i, chance, splcaster, special, statused; int difficulty; + int skill, level; /* Calculate intrinsic ability (splcaster) */ *************** *** 809,820 **** */ chance = 11 * statused / 2; ! /* High level spells are harder. Easier for higher level casters */ ! difficulty = (spellev(spell) - 1) * 4 - (u.ulevel - 1); if (difficulty > 0) { ! /* Player is too low level. Exponential chance reduction */ ! chance -= 7 * difficulty * difficulty; } else { /* Player is above level. Learning continues, but the * law of diminishing returns sets in quickly for --- 1106,1123 ---- */ chance = 11 * statused / 2; ! /* ! * High level spells are harder. Easier for higher level casters. ! * The difficulty is based on the hero's level and their skill level ! * in that spell type. ! */ ! skill = P_SKILL(spell_skilltype(spellid(spell)))-1; ! level = (u.ulevel/3) +1; ! difficulty= (spellev(spell)-1) * 4 - ((skill * 6) + level); if (difficulty > 0) { ! /* Player is too low level or unskilled. */ ! chance -= isqrt(900 * difficulty + 2000); } else { /* Player is above level. Learning continues, but the * law of diminishing returns sets in quickly for *** /home/parsifal/dean/src/nh/uunet/src/u_init.c Sat Apr 5 00:15:09 1997 --- src/u_init.c Sat Apr 5 08:58:36 1997 *************** *** 153,159 **** static struct trobj Wizard[] = { #define W_MULTSTART 2 #define W_MULTEND 6 ! { ATHAME, 1, WEAPON_CLASS, 1, 1 }, /* for dealing with ghosts */ { CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_CLASS, 1, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, WAND_CLASS, 1, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, --- 153,159 ---- static struct trobj Wizard[] = { #define W_MULTSTART 2 #define W_MULTEND 6 ! { QUARTERSTAFF, 1, WEAPON_CLASS, 1, 1 }, /* for dealing with ghosts */ { CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_CLASS, 1, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, WAND_CLASS, 1, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS }, *************** *** 160,165 **** --- 160,166 ---- { UNDEF_TYP, UNDEF_SPE, POTION_CLASS, 3, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, SCROLL_CLASS, 3, UNDEF_BLESS }, { UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, UNDEF_BLESS }, + { SPE_FORCE_BOLT, 0, SPBOOK_CLASS, 1, 1 }, { 0, 0, 0, 0, 0 } }; *************** *** 210,216 **** { P_CLUB, P_SKILLED }, { P_QUARTERSTAFF, P_SKILLED }, { P_SLING, P_SKILLED }, { P_DART, P_BASIC }, { P_BOOMERANG, P_EXPERT }, { P_WHIP, P_EXPERT }, ! { P_UNICORN_HORN, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_BASIC }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } }; --- 211,220 ---- { P_CLUB, P_SKILLED }, { P_QUARTERSTAFF, P_SKILLED }, { P_SLING, P_SKILLED }, { P_DART, P_BASIC }, { P_BOOMERANG, P_EXPERT }, { P_WHIP, P_EXPERT }, ! { P_UNICORN_HORN, P_SKILLED }, ! { P_ATTACK_SPELL, P_BASIC }, { P_HEALING_SPELL, P_BASIC }, ! { P_DIVINATION_SPELL, P_EXPERT}, { P_MATTER_SPELL, P_BASIC}, ! { P_TWO_WEAPON_COMBAT, P_BASIC }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } }; *************** *** 225,230 **** --- 229,235 ---- { P_FLAIL, P_BASIC }, { P_HAMMER, P_EXPERT }, { P_QUARTERSTAFF, P_BASIC }, { P_SPEAR, P_SKILLED }, { P_TRIDENT, P_SKILLED }, { P_BOW, P_BASIC }, + { P_ATTACK_SPELL, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_BASIC }, { P_BARE_HANDED_COMBAT, P_GRAND_MASTER }, { P_NO_TYPE, 0 } *************** *** 239,244 **** --- 244,250 ---- { P_POLEARMS, P_SKILLED }, { P_SPEAR, P_EXPERT }, { P_JAVELIN, P_SKILLED }, { P_TRIDENT, P_SKILLED }, { P_BOW, P_EXPERT }, { P_SLING, P_SKILLED }, + { P_ATTACK_SPELL, P_BASIC }, { P_MATTER_SPELL, P_SKILLED }, { P_BOOMERANG, P_EXPERT }, { P_UNICORN_HORN, P_BASIC }, { P_BARE_HANDED_COMBAT, P_GRAND_MASTER }, { P_NO_TYPE, 0 } *************** *** 252,257 **** --- 258,265 ---- { P_SPEAR, P_EXPERT }, { P_JAVELIN, P_BASIC }, { P_BOW, P_EXPERT }, { P_SLING, P_BASIC }, { P_CROSSBOW, P_BASIC }, { P_SHURIKEN, P_BASIC }, + { P_ATTACK_SPELL, P_SKILLED }, { P_HEALING_SPELL, P_SKILLED }, + { P_ENCHANTMENT_SPELL, P_EXPERT }, { P_TWO_WEAPON_COMBAT, P_EXPERT }, { P_BARE_HANDED_COMBAT, P_SKILLED }, { P_NO_TYPE, 0 } *************** *** 266,271 **** --- 274,280 ---- { P_JAVELIN, P_BASIC }, { P_TRIDENT, P_BASIC }, { P_SLING, P_SKILLED }, { P_DART, P_EXPERT }, { P_SHURIKEN, P_SKILLED }, { P_UNICORN_HORN, P_EXPERT }, + { P_HEALING_SPELL, P_EXPERT }, { P_BARE_HANDED_COMBAT, P_BASIC }, { P_NO_TYPE, 0 } }; *************** *** 282,287 **** --- 291,298 ---- { P_SPEAR, P_SKILLED }, { P_JAVELIN, P_SKILLED }, { P_TRIDENT, P_BASIC }, { P_LANCE, P_EXPERT }, { P_BOW, P_BASIC }, { P_CROSSBOW, P_SKILLED }, + { P_ATTACK_SPELL, P_SKILLED }, { P_HEALING_SPELL, P_SKILLED }, + { P_CLERIC_SPELL, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_SKILLED }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } *************** *** 297,302 **** --- 308,315 ---- { P_SLING, P_BASIC }, { P_CROSSBOW, P_BASIC }, { P_DART, P_BASIC }, { P_SHURIKEN, P_BASIC }, { P_BOOMERANG, P_BASIC }, { P_UNICORN_HORN, P_SKILLED }, + { P_HEALING_SPELL, P_EXPERT }, { P_DIVINATION_SPELL, P_EXPERT }, + { P_CLERIC_SPELL, P_EXPERT }, { P_MARTIAL_ARTS, P_BASIC }, /* until Monk finally gets added */ { P_NO_TYPE, 0 } }; *************** *** 311,316 **** --- 324,331 ---- { P_HAMMER, P_BASIC }, { P_POLEARMS, P_BASIC }, { P_SPEAR, P_BASIC }, { P_CROSSBOW, P_EXPERT }, { P_DART, P_EXPERT }, { P_SHURIKEN, P_SKILLED }, + { P_DIVINATION_SPELL, P_SKILLED }, { P_ESCAPE_SPELL, P_SKILLED }, + { P_MATTER_SPELL, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_EXPERT }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } *************** *** 325,330 **** --- 340,346 ---- { P_POLEARMS, P_SKILLED }, { P_SPEAR, P_BASIC }, { P_JAVELIN, P_BASIC }, { P_LANCE, P_SKILLED }, { P_BOW, P_EXPERT }, { P_SHURIKEN, P_EXPERT }, + { P_ATTACK_SPELL, P_SKILLED }, { P_CLERIC_SPELL, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_EXPERT }, { P_MARTIAL_ARTS, P_GRAND_MASTER }, { P_NO_TYPE, 0 } *************** *** 346,351 **** --- 362,369 ---- { P_CROSSBOW, P_BASIC }, { P_DART, P_EXPERT }, { P_SHURIKEN, P_BASIC }, { P_BOOMERANG, P_BASIC }, { P_WHIP, P_BASIC }, { P_UNICORN_HORN, P_SKILLED }, + { P_DIVINATION_SPELL, P_BASIC }, { P_ENCHANTMENT_SPELL, P_BASIC }, + { P_ESCAPE_SPELL, P_SKILLED }, { P_TWO_WEAPON_COMBAT, P_SKILLED }, { P_BARE_HANDED_COMBAT, P_SKILLED }, { P_NO_TYPE, 0 } *************** *** 361,367 **** { P_QUARTERSTAFF, P_BASIC }, { P_POLEARMS, P_SKILLED }, { P_SPEAR, P_SKILLED }, { P_JAVELIN, P_BASIC }, { P_TRIDENT, P_BASIC }, { P_LANCE, P_SKILLED }, ! { P_SLING, P_BASIC }, { P_TWO_WEAPON_COMBAT, P_SKILLED }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } }; --- 379,387 ---- { P_QUARTERSTAFF, P_BASIC }, { P_POLEARMS, P_SKILLED }, { P_SPEAR, P_SKILLED }, { P_JAVELIN, P_BASIC }, { P_TRIDENT, P_BASIC }, { P_LANCE, P_SKILLED }, ! { P_SLING, P_BASIC }, ! { P_ATTACK_SPELL, P_BASIC }, { P_ESCAPE_SPELL, P_BASIC }, ! { P_TWO_WEAPON_COMBAT, P_SKILLED }, { P_BARE_HANDED_COMBAT, P_EXPERT }, { P_NO_TYPE, 0 } }; *************** *** 374,379 **** --- 394,403 ---- { P_SPEAR, P_BASIC }, { P_JAVELIN, P_BASIC }, { P_TRIDENT, P_BASIC }, { P_SLING, P_SKILLED }, { P_DART, P_EXPERT }, { P_SHURIKEN, P_BASIC }, + { P_ATTACK_SPELL, P_EXPERT }, { P_HEALING_SPELL, P_SKILLED }, + { P_DIVINATION_SPELL, P_EXPERT }, { P_ENCHANTMENT_SPELL, P_SKILLED }, + { P_CLERIC_SPELL, P_SKILLED }, { P_ESCAPE_SPELL, P_EXPERT }, + { P_MATTER_SPELL, P_EXPERT }, { P_BARE_HANDED_COMBAT, P_BASIC }, { P_NO_TYPE, 0 } }; *************** *** 472,477 **** --- 496,502 ---- u.ulevel = 0; /* set up some of the initial attributes */ u.uhp = u.uhpmax = newhp(); + u.uspellprot = 0; adjabil(0,1); u.ulevel = 1; *** /home/parsifal/dean/src/nh/uunet/src/uhitm.c Sat Apr 5 00:14:11 1997 --- src/uhitm.c Sat Apr 12 15:15:04 1997 *************** *** 695,701 **** /* to be valid a projectile must have had the correct projector */ wep = PROJECTILE(obj) ? uwep : obj; tmp += weapon_dam_bonus(wep); ! use_skill(weapon_type(wep)); } #endif /* WEAPON_SKILLS */ --- 695,701 ---- /* to be valid a projectile must have had the correct projector */ wep = PROJECTILE(obj) ? uwep : obj; tmp += weapon_dam_bonus(wep); ! use_skill(weapon_type(wep), 1); } #endif /* WEAPON_SKILLS */ *** /home/parsifal/dean/src/nh/uunet/src/weapon.c Sat Apr 5 00:14:12 1997 --- src/weapon.c Sat Apr 5 08:25:56 1997 *************** *** 25,41 **** PN_POLEARMS, SPEAR, JAVELIN, TRIDENT, LANCE, BOW, SLING, CROSSBOW, DART, SHURIKEN, BOOMERANG, BULLWHIP, ! UNICORN_HORN, PN_TWO_WEAPONS, PN_BARE_HANDED, }; /* note: entry [0] isn't used */ STATIC_OVL NEARDATA const char *odd_skill_names[] = { ! 0, "polearms", "saber", "two weapon combat", "bare handed combat", "martial arts", }; ! static NEARDATA const char may_advance_msg[] = ! "feel more confident in your fighting skills."; #endif /* OVLB */ --- 25,65 ---- PN_POLEARMS, SPEAR, JAVELIN, TRIDENT, LANCE, BOW, SLING, CROSSBOW, DART, SHURIKEN, BOOMERANG, BULLWHIP, ! UNICORN_HORN, ! PN_ATTACK_SPELL, PN_HEALING_SPELL, PN_DIVINATION_SPELL, ! PN_ENCHANTMENT_SPELL, PN_CLERIC_SPELL, PN_ESCAPE_SPELL, ! PN_MATTER_SPELL, PN_CLASSLESS_SPELL, ! PN_TWO_WEAPONS, PN_BARE_HANDED, }; /* note: entry [0] isn't used */ STATIC_OVL NEARDATA const char *odd_skill_names[] = { ! 0, "polearms", "saber", ! "attack spells", ! "healing spells", ! "divination spells", ! "enchantment spells", ! "cleric spells", ! "escape spells", ! "matter spells", ! "classless spells", ! "two weapon combat", "bare handed combat", "martial arts", }; ! static ! void give_may_advance_msg(skill) ! int skill; ! { ! You("feel more confident in your %sskills.", ! skill == P_NO_TYPE ? ! "" : ! skill <= P_LAST_WEAPON ? ! "weapon " : ! skill <= P_LAST_SPELL ? ! "spell casting " : ! "fighting "); ! } #endif /* OVLB */ *************** *** 756,771 **** #ifdef WEAPON_SKILLS void ! use_skill(skill) int skill; { boolean advance_before; if (skill != P_NO_TYPE && !P_RESTRICTED(skill)) { advance_before = can_advance(skill); ! P_ADVANCE(skill)++; if (!advance_before && can_advance(skill)) ! You(may_advance_msg); } } --- 780,796 ---- #ifdef WEAPON_SKILLS void ! use_skill(skill,degree) int skill; + int degree; { boolean advance_before; if (skill != P_NO_TYPE && !P_RESTRICTED(skill)) { advance_before = can_advance(skill); ! P_ADVANCE(skill)+=degree; if (!advance_before && can_advance(skill)) ! give_may_advance_msg(skill); } } *************** *** 781,787 **** for (i = 0, after = 0; i < P_NUM_SKILLS; i++) if (can_advance(i)) after++; if (before < after) ! You(may_advance_msg); } void --- 806,812 ---- for (i = 0, after = 0; i < P_NUM_SKILLS; i++) if (can_advance(i)) after++; if (before < after) ! give_may_advance_msg(P_NO_TYPE); } void *************** *** 995,1000 **** --- 1020,1035 ---- P_SKILL(skill) = P_BASIC; } + /* set skills for magic */ + if (Role_is('H')) { + P_SKILL(P_HEALING_SPELL) = P_BASIC; + } else if (Role_is('P')) { + P_SKILL(P_CLERIC_SPELL) = P_BASIC; + } else if (Role_is('W')) { + P_SKILL(P_ATTACK_SPELL) = P_BASIC; + P_SKILL(P_ENCHANTMENT_SPELL) = P_BASIC; + } + /* walk through array to set skill maximums */ for (; class_skill->skill != P_NO_TYPE; class_skill++) { skmax = class_skill->skmax; *** /home/parsifal/dean/src/nh/uunet/src/zap.c Mon Apr 7 11:46:34 1997 --- src/zap.c Mon Apr 14 22:54:40 1997 *************** *** 30,36 **** STATIC_DCL void FDECL(revive_egg, (struct obj *)); #ifdef OVLB ! static int FDECL(zap_hit, (int)); #endif #ifdef OVL0 static void FDECL(backfire, (struct obj *)); --- 30,36 ---- STATIC_DCL void FDECL(revive_egg, (struct obj *)); #ifdef OVLB ! static int FDECL(zap_hit, (int,int)); #endif #ifdef OVL0 static void FDECL(backfire, (struct obj *)); *************** *** 48,55 **** #define ZT_WAND(x) (x) #define ZT_SPELL(x) (10+(x)) ! #define ZT_BREATH(x) (20+(x)) #ifndef OVLB STATIC_VAR const char are_blinded_by_the_flash[]; extern const char *flash_types[]; --- 48,57 ---- #define ZT_WAND(x) (x) #define ZT_SPELL(x) (10+(x)) ! #define ZT_BREATH(x) (20+(x)) + #define is_hero_spell(type) ((type) >= 10 && (type) < 20) + #ifndef OVLB STATIC_VAR const char are_blinded_by_the_flash[]; extern const char *flash_types[]; *************** *** 95,110 **** /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ int bhitm(mtmp, otmp) ! register struct monst *mtmp; ! register struct obj *otmp; { ! register boolean wake = TRUE; /* Most 'zaps' should wake monster */ ! register int otyp = otmp->otyp; boolean dbldam = Role_is('K') && u.uhave.questart; ! register int dmg; switch(otyp) { case WAN_STRIKING: case SPE_FORCE_BOLT: if (resists_magm(mtmp)) { /* match effect on player */ shieldeff(mtmp->mx, mtmp->my); --- 97,114 ---- /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ int bhitm(mtmp, otmp) ! struct monst *mtmp; ! struct obj *otmp; { ! boolean wake = TRUE; /* Most 'zaps' should wake monster */ boolean dbldam = Role_is('K') && u.uhave.questart; ! int dmg, otyp = otmp->otyp; ! char *zap_type_text = "spell"; switch(otyp) { case WAN_STRIKING: + zap_type_text = "wand"; + /* fall through */ case SPE_FORCE_BOLT: if (resists_magm(mtmp)) { /* match effect on player */ shieldeff(mtmp->mx, mtmp->my); *************** *** 112,121 **** } else if (u.uswallow || rnd(20) < 10 + find_mac(mtmp)) { dmg = d(2,12); if(dbldam) dmg *= 2; ! hit((otyp == WAN_STRIKING) ? "wand" : "spell", ! mtmp, exclam(dmg)); (void) resist(mtmp, otmp->oclass, dmg, TELL); ! } else miss((otyp == WAN_STRIKING) ? "wand" : "spell", mtmp); makeknown(otyp); break; case WAN_SLOW_MONSTER: --- 116,126 ---- } else if (u.uswallow || rnd(20) < 10 + find_mac(mtmp)) { dmg = d(2,12); if(dbldam) dmg *= 2; ! if (otyp == SPE_FORCE_BOLT) ! dmg += spell_damage_bonus(); ! hit(zap_type_text, mtmp, exclam(dmg)); (void) resist(mtmp, otmp->oclass, dmg, TELL); ! } else miss(zap_type_text, mtmp); makeknown(otyp); break; case WAN_SLOW_MONSTER: *************** *** 144,149 **** --- 149,156 ---- wake = TRUE; dmg = rnd(8); if(dbldam) dmg *= 2; + if (otyp == SPE_TURN_UNDEAD) + dmg += spell_damage_bonus(); if(!resist(mtmp, otmp->oclass, dmg, NOTELL)) mtmp->mflee = TRUE; } *************** *** 201,207 **** } expels(mtmp, mtmp->data, TRUE); } ! break; case SPE_HEALING: case SPE_EXTRA_HEALING: wake = FALSE; /* wakeup() makes the target angry */ --- 208,214 ---- } expels(mtmp, mtmp->data, TRUE); } ! break; case SPE_HEALING: case SPE_EXTRA_HEALING: wake = FALSE; /* wakeup() makes the target angry */ *************** *** 1663,1668 **** --- 1670,1722 ---- #endif /*OVLB*/ #ifdef OVL0 + /* + * Generate the to damage bonus for a spell. Based on the hero's intelligence + */ + int + spell_damage_bonus() + { + int tmp, intell = ACURR(A_INT); + + /* Punish low intellegence before low level else low intellegence + gets punished only when high level */ + if (intell < 10) tmp=-3; + else if (u.ulevel < 5) tmp=0; + else if (intell < 14) tmp=0; + else if (intell <= 18) tmp=1; + else tmp=2; /* Hero may have helm of brilliance on */ + + return tmp; + } + + /* + * Generate the to hit bonus for a spell. Based on the hero's skill in + * spell class and dexterity. + */ + int + spell_hit_bonus(skill) + int skill; + { + int hit_bon=0; + int dex = ACURR(A_DEX); + + switch (P_SKILL(spell_skilltype(skill))) { + case P_ISRESTRICTED: + case P_UNSKILLED: hit_bon = -4; break; + case P_BASIC: hit_bon = 0; break; + case P_SKILLED: hit_bon = 2; break; + case P_EXPERT: hit_bon = 3; break; + } + + if (dex < 4) hit_bon-=3; + else if (dex < 6) hit_bon-=2; + else if (dex < 8) hit_bon-=1; + else if (dex < 14) hit_bon-=0;/* Will change when print stuff below removed */ + else hit_bon+=dex-14; /* Even increment for dexterious hero's (see weapon.c abon */ + + return hit_bon; + } + const char * exclam(force) register int force; *************** *** 1921,1926 **** --- 1975,1983 ---- register int tmp = 0; register int abstype = abs(type) % 10; boolean sho_shieldeff = FALSE; + #ifdef WIZ_PATCH_DEBUG + boolean spellcaster = is_hero_spell(type); /* maybe get a bonus! */ + #endif *ootmp = (struct obj *)0; switch(abstype) { *************** *** 1930,1935 **** --- 1987,1999 ---- break; } tmp = d(nd,6); + #ifdef WIZ_PATCH_DEBUG + pline("Normal damage = %d",tmp); + if (spellcaster) { + tmp += spell_damage_bonus(); + pline("Damage changed = %d",tmp); + } + #endif break; case ZT_FIRE: if (resists_fire(mon)) { *************** *** 1938,1943 **** --- 2002,2014 ---- } tmp = d(nd,6); if (resists_cold(mon)) tmp += 7; + #ifdef WIZ_PATCH_DEBUG + pline("Normal damage = %d",tmp); + if (spellcaster) { + tmp += spell_damage_bonus(); + pline("Damage changed = %d",tmp); + } + #endif break; case ZT_COLD: if (resists_cold(mon)) { *************** *** 1946,1951 **** --- 2017,2029 ---- } tmp = d(nd,6); if (resists_fire(mon)) tmp += d(nd, 3); + #ifdef WIZ_PATCH_DEBUG + pline("Normal damage = %d",tmp); + if (spellcaster) { + tmp += spell_damage_bonus(); + pline("Damage changed = %d",tmp); + } + #endif break; case ZT_SLEEP: tmp = 0; *************** *** 2002,2007 **** --- 2080,2092 ---- /* can still blind the monster */ } else tmp = d(nd,6); + #ifdef WIZ_PATCH_DEBUG + pline("Normal damage = %d",tmp); + if (spellcaster) { + tmp += spell_damage_bonus(); + pline("Damage changed = %d",tmp); + } + #endif if (!resists_blnd(mon) && !(type > 0 && u.uswallow && mon == u.ustuck)) { register unsigned rnd_tmp = rnd(50); *************** *** 2027,2037 **** break; } if (sho_shieldeff) shieldeff(mon->mx, mon->my); ! if ((type >= 10 && type <= 19) && (Role_is('K') && u.uhave.questart)) tmp *= 2; if (tmp > 0 && type >= 0 && resist(mon, type < ZT_SPELL(0) ? WAND_CLASS : '\0', 0, NOTELL)) tmp /= 2; mon->mhp -= tmp; return(tmp); } --- 2112,2133 ---- break; } if (sho_shieldeff) shieldeff(mon->mx, mon->my); ! if (is_hero_spell(type) && (Role_is('K') && u.uhave.questart)) { tmp *= 2; + #ifdef WIZ_PATCH_DEBUG + pline("Normal damage = %d",tmp); + if (spellcaster) { + tmp += spell_damage_bonus(); + pline("Damage changed = %d",tmp); + } + #endif + } if (tmp > 0 && type >= 0 && resist(mon, type < ZT_SPELL(0) ? WAND_CLASS : '\0', 0, NOTELL)) tmp /= 2; + #ifdef WIZ_PATCH_DEBUG + pline("zapped monster hp = %d (= %d - %d)", mon->mhp-tmp,mon->mhp,tmp); + #endif mon->mhp -= tmp; return(tmp); } *************** *** 2206,2223 **** /* will zap/spell/breath attack score a hit against armor class `ac'? */ static int ! zap_hit(ac) int ac; { int chance = rn2(20); /* small chance for naked target to avoid being hit */ ! if (!chance) return rnd(10) < ac; /* very high armor protection does not achieve invulnerability */ ac = AC_VALUE(ac); ! ! return (3 - chance) < ac; } /* type == 0 to 9 : you shooting a wand */ --- 2302,2321 ---- /* will zap/spell/breath attack score a hit against armor class `ac'? */ static int ! zap_hit(ac, type) int ac; + int type; /* either hero cast spell type or 0 */ { int chance = rn2(20); + int spell_bonus = type ? spell_hit_bonus(type) : 0; /* small chance for naked target to avoid being hit */ ! if (!chance) return rnd(10) < ac+spell_bonus; /* very high armor protection does not achieve invulnerability */ ac = AC_VALUE(ac); ! ! return (3 - chance) < ac+spell_bonus; } /* type == 0 to 9 : you shooting a wand */ *************** *** 2241,2247 **** --- 2339,2349 ---- boolean shopdamage = FALSE; register const char *fltxt; struct obj *otmp; + int spell_type; + /* if its a Hero Spell then get its SPE_TYPE */ + spell_type = is_hero_spell(type) ? SPE_MAGIC_MISSILE + abstype : 0; + fltxt = flash_types[(type <= -30) ? abstype : abs(type)]; if(u.uswallow) { register int tmp; *************** *** 2285,2291 **** if ((mon = m_at(sx, sy)) != 0) { if (type == ZT_SPELL(ZT_FIRE)) break; if (type >= 0) mon->mstrategy &= ~STRAT_WAITMASK; ! if (zap_hit(find_mac(mon))) { if (mon_reflects(mon, (char *)0)) { if(cansee(mon->mx,mon->my)) { hit(fltxt, mon, exclam(0)); --- 2387,2393 ---- if ((mon = m_at(sx, sy)) != 0) { if (type == ZT_SPELL(ZT_FIRE)) break; if (type >= 0) mon->mstrategy &= ~STRAT_WAITMASK; ! if (zap_hit(find_mac(mon), spell_type)) { if (mon_reflects(mon, (char *)0)) { if(cansee(mon->mx,mon->my)) { hit(fltxt, mon, exclam(0)); *************** *** 2377,2383 **** } } else if (sx == u.ux && sy == u.uy && range >= 0) { nomul(0); ! if (zap_hit((int) u.uac)) { range -= 2; pline("%s hits you!", The(fltxt)); if (Reflecting) { --- 2479,2485 ---- } } else if (sx == u.ux && sy == u.uy && range >= 0) { nomul(0); ! if (zap_hit((int) u.uac, 0)) { range -= 2; pline("%s hits you!", The(fltxt)); if (Reflecting) {