[BACK]Return to magic.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / urogue

Annotation of early-roguelike/urogue/magic.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     magic.c - This file contains functions for casting magic spells
                      3:
                      4:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
                      5:     Copyright (C) 1986, 1992, 1993, 1995 Herb Chong
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <stdlib.h>
                     20: #include <string.h>
                     21: #include <ctype.h>
                     22: #include "rogue.h"
                     23:
                     24: /*
                     25:          Cost for each level of spells level:
                     26: */
                     27:
                     28: static const int spell_cost[] = {1, 5, 17, 29, 53, 91, 159, 247, 396};
                     29:
                     30: static struct spells monst_spells[] =
                     31: {
                     32:     {5, S_SELFTELEP, SCR_MAGIC},
                     33:     {4, P_HEALING, POT_MAGIC | _TWO_},
                     34:     {3, P_REGENERATE, POT_MAGIC},
                     35:     {2, P_HEALING, POT_MAGIC},
                     36:     {4, P_HASTE, POT_MAGIC},
                     37:     {2, P_SEEINVIS, POT_MAGIC},
                     38:     {3, P_SHERO, POT_MAGIC},
                     39:     {5, P_PHASE, POT_MAGIC},
                     40:     {4, P_INVIS, POT_MAGIC},
                     41:     {4, WS_CANCEL, ZAP_MAGIC},
                     42:
                     43:     /* In reverse order of damage ability */
                     44:     {6, WS_ELECT, ZAP_MAGIC | _TWO_},
                     45:     {6, WS_FIRE, ZAP_MAGIC | _TWO_},
                     46:     {6, WS_COLD, ZAP_MAGIC | _TWO_},
                     47:     {6, WS_MISSILE, ZAP_MAGIC | _TWO_},
                     48:     {5, WS_ELECT, ZAP_MAGIC},
                     49:     {5, WS_FIRE, ZAP_MAGIC},
                     50:     {5, WS_COLD, ZAP_MAGIC},
                     51:     {4, WS_ELECT, ZAP_MAGIC | ISCURSED},
                     52:     {4, WS_FIRE, ZAP_MAGIC | ISCURSED},
                     53:     {4, WS_COLD, ZAP_MAGIC | ISCURSED},
                     54:     {3, WS_MISSILE, ZAP_MAGIC},
                     55:     {1, WS_MISSILE, ZAP_MAGIC | ISCURSED},
                     56:
                     57:     {-1, -1, 0}
                     58: };
                     59:
                     60: /*
                     61:     Spells that a player can cast Non-mus only know ISKNOW spells until found
                     62:     in the dungeon. Special classes know their spells one level lower, and
                     63:     blessed one above.
                     64: */
                     65:
                     66: static struct spells player_spells[] =
                     67: {
                     68:     {1, WS_KNOCK, ZAP_MAGIC | ISKNOW},
                     69:     {1, S_SUMFAMILIAR, SCR_MAGIC | SP_DRUID | SP_MAGIC | SP_CLERIC, SP_ILLUSION },
                     70:     {1, S_GFIND, SCR_MAGIC | ISKNOW},
                     71:     {1, P_MONSTDET, POT_MAGIC | ISKNOW | SP_DRUID},
                     72:     {1, P_TREASDET, POT_MAGIC | ISKNOW | SP_MAGIC},
                     73:     {1, S_FOODDET, SCR_MAGIC | ISKNOW | SP_CLERIC},
                     74:     {1, S_LIGHT, SCR_MAGIC | ISKNOW | SP_ILLUSION},
                     75:
                     76:     {2, WS_CLOSE, ZAP_MAGIC | ISKNOW},
                     77:     {2, S_IDENTIFY, SCR_MAGIC | ISKNOW},
                     78:     {2, WS_HIT, ZAP_MAGIC | ISKNOW | SP_PRAYER},
                     79:     {2, P_SHIELD, POT_MAGIC | ISKNOW | SP_MAGIC},
                     80:     {2, P_COLDRESIST, POT_MAGIC | SP_WIZARD},
                     81:     {2, P_SEEINVIS, POT_MAGIC | SP_ILLUSION},
                     82:     {2, S_CONFUSE, SCR_MAGIC | SP_CLERIC},
                     83:     {2, P_SMELL, POT_MAGIC | SP_DRUID},
                     84:     {2, WS_MISSILE, ZAP_MAGIC | SP_MAGIC},
                     85:     {2, P_HEAR, POT_MAGIC},
                     86:
                     87:     {3, P_CLEAR, POT_MAGIC | ISKNOW},
                     88:     {3, P_HEALING, POT_MAGIC | ISKNOW | SP_PRAYER},
                     89:     {3, S_CURING, SCR_MAGIC | ISKNOW | SP_PRAYER},
                     90:     {3, WS_MONSTELEP, ZAP_MAGIC | SP_MAGIC},
                     91:     {3, WS_CANCEL, ZAP_MAGIC | SP_WIZARD},
                     92:     {3, S_SELFTELEP, SCR_MAGIC | SP_WIZARD},
                     93:     {3, P_FIRERESIST, POT_MAGIC | SP_WIZARD | SP_DRUID},
                     94:     {3, S_MAP, SCR_MAGIC | SP_ILLUSION | SP_DRUID},
                     95:     {3, S_REMOVECURSE, SCR_MAGIC | SP_PRAYER},
                     96:     {3, S_HOLD, SCR_MAGIC | SP_CLERIC},
                     97:     {3, S_SLEEP, SCR_MAGIC | SP_DRUID},
                     98:     {3, P_HASOXYGEN, POT_MAGIC | SP_DRUID},
                     99:     {3, WS_XENOHEALING, ZAP_MAGIC | SP_DRUID},
                    100:     {3, P_RESTORE, POT_MAGIC},
                    101:
                    102:     {4, S_MSHIELD, SCR_MAGIC | ISKNOW | SP_ILLUSION},
                    103:     {4, P_INVIS, POT_MAGIC | SP_ILLUSION},
                    104:     {4, S_REFLECT, SCR_MAGIC | SP_ILLUSION},
                    105:     {4, P_TRUESEE, POT_MAGIC | SP_ILLUSION},
                    106:     {4, P_REGENERATE, POT_MAGIC | SP_CLERIC},
                    107:     {4, WS_DRAIN, ZAP_MAGIC | SP_CLERIC},
                    108:     {4, P_HASTE, POT_MAGIC | SP_ILLUSION | SP_CLERIC},
                    109:     {4, P_LEVITATION, POT_MAGIC | SP_WIZARD | SP_DRUID},
                    110:     {4, WS_WEB, ZAP_MAGIC | SP_MAGIC},
                    111:     {4, P_PHASE, POT_MAGIC},
                    112:
                    113:     {5, P_SHERO, POT_MAGIC | ISKNOW},
                    114:     {5, S_PETRIFY, SCR_MAGIC | SP_MAGIC},
                    115:     {5, S_SCARE, SCR_MAGIC | _TWO_ | SP_PRAYER},
                    116:     {5, WS_COLD, ZAP_MAGIC | SP_DRUID},
                    117:     {5, WS_FIRE, ZAP_MAGIC | SP_CLERIC},
                    118:     {5, WS_ELECT, ZAP_MAGIC | SP_WIZARD},
                    119:     {5, WS_ANTIMATTER, ZAP_MAGIC | SP_ILLUSION},
                    120:     {5, S_ELECTRIFY, SCR_MAGIC | SP_ILLUSION},
                    121:
                    122:     {6, WS_DISINTEGRATE, ZAP_MAGIC | ISKNOW},
                    123:     {6, S_OWNERSHIP, SCR_MAGIC | SP_ALL},
                    124:
                    125:     {7, S_ENCHANT, SCR_MAGIC | SP_MAGIC},
                    126:
                    127:     {-1, -1, 0}
                    128: };
                    129:
                    130: /*
                    131:     incant()
                    132:        Cast a spell
                    133: */
                    134:
                    135: void
                    136: incant(struct thing *caster, coord dir)
                    137: {
                    138:     int i;
                    139:     struct stats    *curp;
                    140:     struct stats    *maxp;
                    141:     int is_player = (caster == &player);
                    142:     int points_casters;
                    143:     char    *casters_name = (on(player, ISBLIND)) ? "it" :
                    144:             monsters[caster->t_index].m_name;
                    145:     struct spells   *sp;
                    146:     char *cast_name;                      /* = spell_name(sp)           */
                    147:     char *spell_type;                     /* spell or prayer            */
                    148:     int   casting_cost;                   /* from spell_cost[]          */
                    149:     int   spell_roll;                     /* sucess/fail 1D100 die roll */
                    150:     int   fumble_chance;                  /* Spell fumble chance        */
                    151:     int   num_fumbles = 0;                /* for fumble_spell()         */
                    152:     int   bless_or_curse = ISNORMAL;      /* blessed or cursed?         */
                    153:     int   message_flags = CAST_NORMAL;    /* which message to print out */
                    154:     int   class_casters;                  /* For determining ISKNOW     */
                    155:     int   stat_casters;                   /* s_intel or s_wisdom        */
                    156:     int   level_casters;                  /* spellcasting level         */
                    157:     char  buf[2 * LINELEN];
                    158:     struct spells sorted_spells[MAX_SPELLS];
                    159:     char  spellbuf[2 * LINELEN];
                    160:     char  spellbuf2[2 * LINELEN];
                    161:
                    162:     curp = &(caster->t_stats);
                    163:     maxp = &(caster->maxstats);
                    164:     points_casters = curp->s_power;
                    165:
                    166:     if (points_casters <= 0)
                    167:     {
                    168:         if (is_player)
                    169:             msg("You don't have any spell points.");
                    170:
                    171:         return;
                    172:     }
                    173:
                    174:     /*
                    175:      * Paladins, Rangers, ringwearers, and monsters cast at 4 levels
                    176:      * below. Other non-specialists at 8 below
                    177:     */
                    178:
                    179:     level_casters = curp->s_lvl;
                    180:
                    181:     switch (caster->t_ctype)
                    182:     {
                    183:         case C_PALADIN:
                    184:             level_casters -= 4;
                    185:             /* fallthrough */
                    186:         case C_CLERIC:
                    187:             class_casters = SP_CLERIC;
                    188:             stat_casters = curp->s_wisdom;
                    189:             break;
                    190:         case C_RANGER:
                    191:             level_casters -= 4;
                    192:             /* fallthrough */
                    193:         case C_DRUID:
                    194:             class_casters = SP_DRUID;
                    195:             stat_casters = curp->s_wisdom;
                    196:             break;
                    197:         case C_MAGICIAN:
                    198:             class_casters = SP_WIZARD;
                    199:             stat_casters = curp->s_intel;
                    200:             break;
                    201:         case C_ILLUSION:
                    202:             class_casters = SP_ILLUSION;
                    203:             stat_casters = curp->s_intel;
                    204:             break;
                    205:         case C_MONSTER:
                    206:             if (off(*caster, ISUNIQUE))
                    207:                 level_casters -= 4;
                    208:             class_casters = 0x0;
                    209:             stat_casters = curp->s_intel;
                    210:             break;
                    211:
                    212:         default:
                    213:             if (is_wearing(R_WIZARD))
                    214:             {
                    215:                 level_casters -= 4;
                    216:                 class_casters = (rnd(4) ? SP_WIZARD : SP_ILLUSION);
                    217:                 stat_casters = curp->s_intel;
                    218:             }
                    219:             else if (is_wearing(R_PIETY))
                    220:             {
                    221:                 level_casters -= 4;
                    222:                 class_casters = (rnd(4) ? SP_CLERIC : SP_DRUID);
                    223:                 stat_casters = curp->s_wisdom;
                    224:             }
                    225:             else
                    226:             {
                    227:                 level_casters -= 8;
                    228:                 class_casters = 0x0;
                    229:                 stat_casters = (rnd(2) ? curp->s_wisdom : curp->s_intel);
                    230:             }
                    231:     }
                    232:
                    233:     /* Bug - What about when WIS == INT? */
                    234:
                    235:     spell_type = (stat_casters == curp->s_intel) ? "spell" : "prayer";
                    236:
                    237:     if (!is_player && (sp = pick_monster_spell(caster)) == NULL)
                    238:             return;
                    239:     else if (is_player)
                    240:     {
                    241:         int num_spells = -1;    /* num of spells cheap enough */
                    242:
                    243:         sorted_spells[0].sp_cost = -1;
                    244:
                    245:         for (sp = player_spells; sp->sp_level != -1; sp++)
                    246:         {
                    247:             if (sp->sp_flags & class_casters)  /* Does class know spell? */
                    248:             {
                    249:                 int rnd_number = rnd(2 * sp->sp_level) - sp->sp_level;
                    250:
                    251:                 /* Knows normal spell one level below others */
                    252:
                    253:                 casting_cost = spell_cost[sp->sp_level - 1] + rnd_number;
                    254:
                    255:                 if (points_casters >= casting_cost)
                    256:                 {
                    257:                     sorted_spells[++num_spells] = *sp;
                    258:                     sorted_spells[num_spells].sp_cost = casting_cost;
                    259:                     sorted_spells[num_spells].sp_level = sp->sp_level - 1;
                    260:                 }
                    261:
                    262:                 /* Knows blessed spell one level above others */
                    263:
                    264:                 casting_cost = spell_cost[sp->sp_level + 1] + rnd_number;
                    265:
                    266:                 if (points_casters >= casting_cost)
                    267:                 {
                    268:                     sorted_spells[++num_spells] = *sp;
                    269:                     sorted_spells[num_spells].sp_level = sp->sp_level + 1;
                    270:                     sorted_spells[num_spells].sp_cost = casting_cost;
                    271:                     sorted_spells[num_spells].sp_flags |= ISBLESSED;
                    272:                 }
                    273:             } /* If class doesn't know spell, see if its a ISKNOW */
                    274:             else if (sp->sp_flags & ISKNOW)
                    275:             {
                    276:                 int rnd_number = rnd(4 * sp->sp_level) - sp->sp_level;
                    277:
                    278:                 casting_cost = spell_cost[sp->sp_level] + rnd_number;
                    279:
                    280:                 if (points_casters >= casting_cost)
                    281:                 {
                    282:                     sorted_spells[++num_spells] = *sp;
                    283:                     sorted_spells[num_spells].sp_cost = casting_cost;
                    284:                 }
                    285:             }
                    286:             /* else this spell is unknown */
                    287:         }
                    288:
                    289:         if (sorted_spells[0].sp_cost == -1)
                    290:         {
                    291:             msg("You don't have enough %s points.", spell_type);
                    292:             after = FALSE;
                    293:             return;
                    294:         }
                    295:
                    296:         qsort(sorted_spells,num_spells + 1,sizeof(struct spells),sort_spells);
                    297:
                    298:         do         /* Prompt for spells */
                    299:         {
                    300:             struct spells   *which_spell = NULL;
                    301:
                    302:             buf[0] = '\0';
                    303:             msg("");/* Get rid of --More-- */
                    304:             msg("Which %s are you casting [%d points left] (* for list)? ",
                    305:                 spell_type, points_casters);
                    306:
                    307:             switch(get_string(buf, cw))
                    308:             {
                    309:                 case NORM:  break;
                    310:                 case QUIT:  return; /* ESC - lose turn */
                    311:                 default:    continue;
                    312:             }
                    313:
                    314:             if (buf[0] == '*')    /* print list */
                    315:             {
                    316:                 add_line("Cost  Abbreviation    Full Name");
                    317:
                    318:                 for (i = 0; i <= num_spells; i++)
                    319:                 {
                    320:                     sp = &sorted_spells[i];
                    321:                     sprintf(buf, "[%3d] %-12s\t%s",
                    322:                         sp->sp_cost, spell_abrev(sp,spellbuf2),
                    323:                         spell_name(sp,spellbuf));
                    324:                     add_line(buf);
                    325:                 }
                    326:                 end_line();
                    327:                 sp = NULL;
                    328:                 continue;
                    329:             }
                    330:
                    331:             if (isupper(buf[0])) /* Uppercase Abbreviation */
                    332:             {
                    333:                 for (i = 0; i <= num_spells; i++)
                    334:                 {
                    335:                     sp = &sorted_spells[i];
                    336:
                    337:                     if ((strcmp(spell_abrev(sp,spellbuf2), buf) == 0))
                    338:                     {
                    339:                         which_spell = sp;
                    340:                         break;
                    341:                     }
                    342:                 }
                    343:             }
                    344:             else /* Full Spell Name */
                    345:             {
                    346:                 for (i = 0; i <= num_spells; i++)
                    347:                 {
                    348:                     sp = &sorted_spells[i];
                    349:
                    350:                     if ((strcmp(spell_name(sp,spellbuf), buf) == 0))
                    351:                     {
                    352:                         which_spell = sp;
                    353:                         break;
                    354:                     }
                    355:                 }
                    356:             }
                    357:
                    358:             sp = which_spell;
                    359:         }
                    360:         while (sp == NULL);
                    361:     }
                    362:
                    363:     /* Common monster and player code */
                    364:
                    365:     cast_name = spell_name(sp,spellbuf);
                    366:
                    367:     fumble_chance = (10 * sp->sp_level / 4 - 10 * level_casters / 13) * 5;
                    368:
                    369:     if (cur_weapon != NULL && wield_ok(caster, cur_weapon, FALSE) == FALSE)
                    370:     {
                    371:         switch (caster->t_ctype)
                    372:         {
                    373:             case C_MAGICIAN:
                    374:             case C_ILLUSION:
                    375:                 msg("You should have both hands free.");
                    376:                 fumble_chance += rnd(level_casters) * 5;
                    377:                 break;
                    378:
                    379:             case C_CLERIC:
                    380:             case C_DRUID:
                    381:             case C_PALADIN:
                    382:                 msg("Your god looks askance at the weapon you wield.");
                    383:                 fumble_chance += rnd(level_casters) * 5;
                    384:                 break;
                    385:
                    386:             default:
                    387:                 break;
                    388:         }
                    389:     }
                    390:
                    391:     if (fumble_chance >= MAX_FUMBLE_CHANCE)
                    392:         fumble_chance = MAX_FUMBLE_CHANCE;
                    393:     else if (fumble_chance <= MIN_FUMBLE_CHANCE + sp->sp_level)
                    394:         fumble_chance = MIN_FUMBLE_CHANCE + sp->sp_level;
                    395:
                    396:     if (fumble_chance > (30 + rnd(50)))
                    397:     {
                    398:         if (is_player)
                    399:         {
                    400:             int  answer;
                    401:
                    402:             msg("Are you sure you want to try for that hard a %s? [n]",
                    403:                 spell_type);
                    404:
                    405:             answer = readchar();
                    406:
                    407:             if (tolower(answer) != 'y')
                    408:             {
                    409:                 after = FALSE;
                    410:                 return;
                    411:             }
                    412:             else
                    413:                 msg("Here goes...");
                    414:         }
                    415:         else  /* Only if the monster is desperate */
                    416:         {
                    417:             if (curp->s_hpt > maxp->s_hpt / 2)
                    418:                 return;
                    419:         }
                    420:     }
                    421:
                    422:        /* casting costs food energy */
                    423:
                    424:        food_left -= sp->sp_cost;
                    425:
                    426:     spell_roll = rnd(100);
                    427:
                    428:     debug("%s(%d) cast '%s' fumble %%%d (rolled %d) ",
                    429:           monsters[caster->t_index].m_name, curp->s_power, cast_name,
                    430:           fumble_chance, spell_roll);
                    431:
                    432:     caster->t_rest_hpt = caster->t_rest_pow = 0;
                    433:
                    434:     if (!is_player)    /* Stop running. */
                    435:     {
                    436:         running = FALSE;
                    437:         msg("The %s is casting '%s'.", casters_name, cast_name);
                    438:     }
                    439:
                    440:     /* The Crown of Might insures that your spells never fumble */
                    441:
                    442:     if (spell_roll < fumble_chance)
                    443:     {
                    444:         if (is_carrying(TR_CROWN))
                    445:             message_flags |= CAST_CROWN;
                    446:         else
                    447:         {
                    448:             message_flags |= CAST_CURSED;
                    449:
                    450:             curp->s_power -= min(curp->s_power,
                    451:                 (2 * sp->sp_cost)); /* 2x cost */
                    452:             num_fumbles = rnd(((fumble_chance - spell_roll) / 10)
                    453:                  + 1) + rnd(sp->sp_level) + rnd(curp->s_lvl);
                    454:             num_fumbles = min(10, max(0, num_fumbles));
                    455:
                    456:             if (num_fumbles >= 6 && rnd(1) == 0)
                    457:                 bless_or_curse = ISCURSED;
                    458:             else if (num_fumbles < 4)
                    459:             {
                    460:                 if (is_player)
                    461:                     msg("Your %s fails.", spell_type);
                    462:                 return;
                    463:             }
                    464:         }
                    465:     }
                    466:     else if (spell_roll > MAX_FUMBLE_CHANCE)
                    467:     {
                    468:         if (is_player)
                    469:         {
                    470:             message_flags |= CAST_BLESSED;
                    471:             pstats.s_exp += 3 * sp->sp_cost * curp->s_lvl;
                    472:             check_level();
                    473:         }
                    474:
                    475:         maxp->s_power += sp->sp_cost;
                    476:         bless_or_curse = ISBLESSED;
                    477:     }
                    478:     else
                    479:     {
                    480:         if (is_player) /* extra exp for sucessful spells */
                    481:         {
                    482:             if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_ILLUSION)
                    483:             {
                    484:                 pstats.s_exp += sp->sp_cost * curp->s_lvl;
                    485:                 check_level();
                    486:             }
                    487:         }
                    488:
                    489:         bless_or_curse = sp->sp_flags & ISBLESSED;
                    490:         curp->s_power -= sp->sp_cost;
                    491:     }
                    492:
                    493:     /* The Sceptre of Might blesses all your spells */
                    494:
                    495:     if (is_player && ((bless_or_curse & ISBLESSED) == 0) &&
                    496:         is_carrying(TR_SCEPTRE))
                    497:     {
                    498:         message_flags |= CAST_SEPTRE;
                    499:         bless_or_curse = ISBLESSED;
                    500:     }
                    501:
                    502:     if (sp->sp_flags & POT_MAGIC)
                    503:         quaff(caster, sp->sp_which, bless_or_curse);
                    504:     else if (sp->sp_flags & SCR_MAGIC)
                    505:             read_scroll(caster, sp->sp_which, bless_or_curse);
                    506:     else if (sp->sp_flags & ZAP_MAGIC)
                    507:     {
                    508:         if (is_player)
                    509:         {
                    510:             do     /* Must pick a direction */
                    511:             {
                    512:                 msg("Which direction?");
                    513:             }
                    514:             while (get_dir() == FALSE);
                    515:         }
                    516:         else
                    517:         {
                    518:             delta.x = dir.x;
                    519:             delta.y = dir.y;
                    520:         }
                    521:         do_zap(caster, sp->sp_which, bless_or_curse);
                    522:     }
                    523:     else
                    524:         msg("What a strange %s!", spell_type);
                    525:
                    526:     /*
                    527:      * Print messages and take fumbles *after* spell has gone off. This
                    528:      * makes ENCHANT, etc more dangerous
                    529:     */
                    530:
                    531:     if (is_player)
                    532:     {
                    533:         if (message_flags & CAST_SEPTRE)
                    534:             msg("The Sceptre enhanced your %s.", spell_type);
                    535:         if (message_flags & CAST_CROWN)
                    536:             msg("The Crown wordlessly corrected your %s.",
                    537:                 spell_type);
                    538:
                    539:         switch (message_flags & 0x1)
                    540:         {
                    541:             case CAST_CURSED:
                    542:                 msg("You botched your '%s' %s.", cast_name,
                    543:                     spell_type);
                    544:                 fumble_spell(caster, num_fumbles);
                    545:                 break;
                    546:             case CAST_NORMAL:
                    547:                 msg("You sucessfully cast your '%s' %s.",
                    548:                     cast_name, spell_type);
                    549:                 break;
                    550:
                    551:             case CAST_BLESSED:
                    552:                 msg("Your '%s' %s went superbly.", cast_name,
                    553:                     spell_type);
                    554:                 break;
                    555:         }
                    556:     }
                    557: }
                    558:
                    559: /*
                    560:     spell_name()
                    561:         returns pointer to spell name
                    562: */
                    563:
                    564: char *
                    565: spell_name(struct spells *sp, char *buf)
                    566: {
                    567:     if (buf == NULL)
                    568:         return("UltraRogue Bug #105");
                    569:
                    570:     if (sp->sp_flags & POT_MAGIC)
                    571:         strcpy(buf, p_magic[sp->sp_which].mi_name);
                    572:     else if (sp->sp_flags & SCR_MAGIC)
                    573:         strcpy(buf, s_magic[sp->sp_which].mi_name);
                    574:     else if (sp->sp_flags & ZAP_MAGIC)
                    575:         strcpy(buf, ws_magic[sp->sp_which].mi_name);
                    576:     else
                    577:         strcpy(buf, "unknown spell type");
                    578:
                    579:     if (sp->sp_flags & ISBLESSED)
                    580:         strcat(buf, " 2");
                    581:
                    582:     return(buf);
                    583: }
                    584:
                    585: /*
                    586:     spell_abrev()
                    587:         returns pointer to capital letter spell abbreviation
                    588: */
                    589:
                    590: char *
                    591: spell_abrev(struct spells *sp, char *buf)
                    592: {
                    593:     if (buf == NULL)
                    594:          return("UltraRogue Bug #106");
                    595:
                    596:     if (sp->sp_flags & POT_MAGIC)
                    597:         strcpy(buf, p_magic[sp->sp_which].mi_abrev);
                    598:     else if (sp->sp_flags & SCR_MAGIC)
                    599:         strcpy(buf, s_magic[sp->sp_which].mi_abrev);
                    600:     else if (sp->sp_flags & ZAP_MAGIC)
                    601:         strcpy(buf, ws_magic[sp->sp_which].mi_abrev);
                    602:     else
                    603:         strcpy(buf, "?????");
                    604:
                    605:     if (sp->sp_flags & ISBLESSED)
                    606:         strcat(buf, " 2");
                    607:
                    608:     return(buf);
                    609: }
                    610:
                    611: /*
                    612:     fumble_spell()
                    613:         he blew it.  Make him pay
                    614: */
                    615:
                    616: void
                    617: fumble_spell(struct thing *caster, int num_fumbles)
                    618: {
                    619:     struct stats    *curp = &(caster->t_stats);
                    620:     struct stats    *maxp = &(caster->maxstats);
                    621:     int    is_player = (caster == &player);
                    622:
                    623:     debug("Taking %d fumbles.", num_fumbles);
                    624:
                    625:     switch (num_fumbles)
                    626:     {
                    627:         case 10: /* Lose ability */
                    628:             if (rnd(5) == 0)
                    629:                 quaff(caster, P_GAINABIL, ISCURSED);
                    630:             break;
                    631:
                    632:         case 9: /* Lose max spell points */
                    633:
                    634:             if (rnd(4) == 0)
                    635:             {
                    636:                 maxp->s_power -= rnd(10);
                    637:
                    638:                 if (maxp->s_power <= 5)
                    639:                     maxp->s_power = 5;
                    640:             }
                    641:             break;
                    642:
                    643:         case 8: /* Lose all current spell points */
                    644:
                    645:             if (rnd(3) == 0)
                    646:                 curp->s_power = 0;
                    647:             else
                    648:                 curp->s_power /= 2;
                    649:             break;
                    650:
                    651:         case 7: /* Freeze */
                    652:
                    653:             if (rnd(2) == 0)
                    654:             {
                    655:                 if (is_player)
                    656:                     no_command++;
                    657:                 else
                    658:                     caster->t_no_move++;
                    659:             }
                    660:             break;
                    661:
                    662:         case 6: /* Cast a cursed spell - see below */
                    663:             break;
                    664:
                    665:         case 5: /* Become dazed and confused */
                    666:
                    667:             if (rnd(5) == 0)
                    668:                 quaff(caster, P_CLEAR, ISCURSED);
                    669:             break;
                    670:
                    671:         case 4: /* Lose hit points */
                    672:
                    673:             if (is_player)
                    674:                 feel_message();
                    675:             if ((curp->s_hpt -= rnd(10)) <= 0)
                    676:             {
                    677:                 if (is_player)
                    678:                     death(D_SPELLFUMBLE);
                    679:                 else
                    680:                     killed(caster, find_mons(caster->t_pos.y, caster->t_pos.x),
                    681:                        NOMESSAGE, NOPOINTS);
                    682:                 return;
                    683:             }
                    684:             break;
                    685:
                    686:         case 3: /* Spell fails */
                    687:             break;
                    688:
                    689:         case 2: /* Freeze */
                    690:
                    691:             if (is_player)
                    692:                 no_command++;
                    693:             else
                    694:                 caster->t_no_move++;
                    695:
                    696:             break;
                    697:
                    698:         default:
                    699:         case 1: /* Take double spell points - handled in incant() */
                    700:             break;
                    701:     }
                    702: }
                    703:
                    704: /*
                    705:     learn_new_spells()
                    706:         go through player_spells and ISKNOW identified potions,
                    707:         scrolls, and sticks
                    708: */
                    709:
                    710: void
                    711: learn_new_spells(void)
                    712: {
                    713:     struct spells   *sp;
                    714:     int kludge = 0;
                    715:     char spellbuf[2*LINELEN];
                    716:
                    717:     for (sp = player_spells; sp->sp_level != -1; sp++)
                    718:     {
                    719:         if (sp->sp_flags & POT_MAGIC)
                    720:             kludge = TYP_POTION;
                    721:         else if (sp->sp_flags & SCR_MAGIC)
                    722:             kludge = TYP_SCROLL;
                    723:         else if (sp->sp_flags & ZAP_MAGIC)
                    724:             kludge = TYP_STICK;
                    725:
                    726:         if (know_items[kludge][sp->sp_which])
                    727:         {
                    728:             if ((sp->sp_flags & ISKNOW) == FALSE)
                    729:                 debug("Learned new spell '%s'", spell_name(sp,spellbuf));
                    730:             sp->sp_flags |= ISKNOW;
                    731:         }
                    732:     }
                    733: }
                    734:
                    735: /*
                    736:     pick_monster_spell()
                    737:         decide which spell from monst_spells will be cast
                    738:         returns pointer to spell in monst_spells
                    739: */
                    740:
                    741: struct spells *
                    742: pick_monster_spell(struct thing *caster)
                    743: {
                    744:     struct spells   *sp = NULL;
                    745:     struct stats    *curp = &(caster->t_stats);
                    746:     int points_casters = curp->s_power;
                    747:
                    748:     /* Discover castable spells */
                    749:
                    750:     for (sp = monst_spells; sp->sp_level != -1; sp++)
                    751:     {
                    752:         int rnd_number = rnd(2 * sp->sp_level) - sp->sp_level;
                    753:         int casting_cost = spell_cost[sp->sp_level] + rnd_number;
                    754:
                    755:         if (points_casters >= casting_cost)
                    756:             sp->sp_flags |= ISKNOW;
                    757:     }
                    758:
                    759:     /* Decide which spell to cast */
                    760:
                    761:     if (curp->s_hpt < rnd(caster->maxstats.s_hpt))  /* think defense */
                    762:     {
                    763:         int i;
                    764:         static const int run_or_heal[NUM_RUN] =
                    765:             { M_SELFTELEP, M_HLNG2, M_HLNG, M_REGENERATE };
                    766:
                    767:         for (i = 0; i < NUM_RUN; i++)
                    768:         {
                    769:             sp = &monst_spells[run_or_heal[i]];
                    770:
                    771:             if ((sp->sp_flags & ISKNOW) && rnd(1))
                    772:                 return(sp);
                    773:         }
                    774:     }
                    775:
                    776:     if (on(*caster, ISSLOW))   /* cancel a slow */
                    777:     {
                    778:         sp = &monst_spells[M_HASTE];
                    779:
                    780:         if (sp->sp_flags & ISKNOW)
                    781:             return (sp);
                    782:     }
                    783:
                    784:     if (on(*caster, ISFLEE))   /* stop running away */
                    785:     {
                    786:         sp = &monst_spells[M_SHERO];
                    787:
                    788:         if (sp->sp_flags & ISKNOW)
                    789:             return (sp);
                    790:     }
                    791:
                    792:     if (on(player, ISINVIS) || on(player, ISDISGUISE))
                    793:     {
                    794:         if (off(*caster, CANSEE))  /* look for him */
                    795:         {
                    796:             sp = &monst_spells[M_SEEINVIS];
                    797:
                    798:             if (sp->sp_flags & ISKNOW)
                    799:                 return (sp);
                    800:         }
                    801:         else if (off(*caster, ISINVIS))    /* go invisible */
                    802:         {
                    803:             sp = &monst_spells[M_INVIS];
                    804:
                    805:             if (sp->sp_flags & ISKNOW)
                    806:                 return (sp);
                    807:         }
                    808:     }
                    809:
                    810:     if (on(player, CANINWALL) && (off(*caster, CANINWALL)) &&
                    811:        (rnd(5) == 0))
                    812:     {
                    813:         sp = &monst_spells[M_PHASE];
                    814:
                    815:         if (sp->sp_flags & ISKNOW)
                    816:             return (sp);
                    817:     }
                    818:
                    819:     if (rnd(5) == 0 && has_defensive_spell(player))
                    820:     {
                    821:         sp = &monst_spells[M_CANCEL];
                    822:
                    823:         if (sp->sp_flags & ISKNOW)
                    824:             return (sp);
                    825:     }
                    826:
                    827:     /* Cast an offensive spell */
                    828:
                    829:     for (sp = &monst_spells[M_OFFENSE]; sp->sp_level != 1; sp++)
                    830:     {
                    831:         if ((rnd(3) == 0) && (sp->sp_flags & ISKNOW))
                    832:             return (sp);
                    833:
                    834:         if ((rnd(3) == 0) && (sp->sp_flags & ISKNOW))
                    835:         {
                    836:             if (sp->sp_which != WS_MISSILE &&
                    837:                 DISTANCE(caster->t_pos, hero) > BOLT_LENGTH)
                    838:                 continue;
                    839:             else
                    840:                 return(sp);
                    841:         }
                    842:     }
                    843:
                    844:     return(NULL);
                    845: }
                    846:
                    847: /*
                    848:     sort_spells()
                    849:        called by qsort()
                    850: */
                    851:
                    852: int
                    853: sort_spells(const void *a, const void *b)
                    854: {
                    855:     struct spells *sp1, *sp2;
                    856:     int diff;
                    857:     char  spellbuf[2 * LINELEN];
                    858:     char  spellbuf2[2 * LINELEN];
                    859:
                    860:     union /* hack to prevent 'lint' from complaining */
                    861:     {
                    862:         struct spells *s;
                    863:         const void          *vptr;
                    864:     } s1,s2;
                    865:
                    866:     s1.vptr = a;
                    867:     s2.vptr = b;
                    868:
                    869:     sp1 = s1.s;
                    870:     sp2 = s2.s;
                    871:
                    872:     diff = sp1->sp_cost - sp2->sp_cost;
                    873:
                    874:     if (diff != 0)
                    875:         return(diff);
                    876:     else
                    877:         return(strcmp(spell_name(sp1,spellbuf), spell_name(sp1,spellbuf2)));
                    878: }

CVSweb