/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ /* spell.c */ /* functions having to do with spellcasting */ #include "glob.h" void s_nutrition(void) { #ifdef TRADEMARK_VIOLATION mprint("Magically Delicious!"); #else mprint("Scrumptious!"); #endif Player.food = 44; foodcheck(); } void s_wish(void) { if (random_range(100) > Player.iq+Player.pow+Player.level) { mprint("Your concentration is flawed!"); mprint("The spell energy backfires!"); p_damage(random_range(Spells[S_WISH].powerdrain), UNSTOPPABLE, "a backfired wish spell"); } else { wish(0); if (Spells[S_WISH].known) { mprint("The power of the spell is too much for you to withstand!"); mprint("All memory of the spell is expunged from your brain."); Spells[S_WISH].known = FALSE; } } } void s_firebolt(void) { int x=Player.x,y=Player.y; setspot(&x,&y); fbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*10+10); } void s_missile(void) { int x=Player.x,y=Player.y; setspot(&x,&y); nbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*3+3); } void s_teleport(void) { p_teleport(0); } void s_disrupt(void) { int x=Player.x,y=Player.y; setspot(&x,&y); disrupt(x,y,Player.level*10+25); } void s_disintegrate(void) { int x=Player.x,y=Player.y; setspot(&x,&y); disintegrate(x,y); } void s_sleep(void) { sleep_monster(0); } void s_heal(void) { heal(3); } void s_dispel(void) { dispel((Player.level+Player.maxpow)/10); } void s_breathe(void) { breathe(0); } void s_invisible(void) { invisible(0); } void s_warp(void) { warp(1); } void s_enchant(void) { enchant(1); } void s_bless(void) { bless(0); } void s_restore(void) { recover_stat(0); } void s_cure(void) { cure(0); } void s_truesight(void) { truesight(0); } void s_hellfire(void) { int x=Player.x,y=Player.y; setspot(&x,&y); hellfire(x,y,0); Spells[S_HELLFIRE].powerdrain *= 2; if (Spells[S_HELLFIRE].powerdrain > 90) /* 90 is original casting cost */ { mprint("The power of the spell is too much for you to withstand!"); mprint("All memory of the spell is expunged from your brain."); Spells[S_HELLFIRE].powerdrain = 90; Spells[S_HELLFIRE].known = FALSE; } } void s_knowledge(void) { knowledge(0); } void s_hero(void) { hero(0); } /* spell takes longer and longer to work deeper into dungeon */ void s_return(void) { mprint("You hear a whine as your spell begins to charge up."); Player.status[RETURNING] = ((Current_Environment == Current_Dungeon) ? difficulty() : 1); } void s_desecrate(void) { sanctify(-1); } void s_haste(void) { haste(0); } void s_summon(void) { summon(0,-1); } void s_sanctuary(void) { sanctuary(); } void s_sanctify(void) { sanctify(1); } void s_accuracy(void) { accuracy(0); } void s_fear(void) { int x = Player.x,y=Player.y; setspot(&x,&y); inflict_fear(x,y); } /* Has all kinds of effects in different circumstances. Eventually will be more interesting */ void s_ritual(void) { pob symbol; int i,roomno; int x,y; mprint("You begin your ritual...."); mprint("You enter a deep trance. Time Passes..."); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); if (RitualHour == hour()) mprint("Your mental fatigue prevents from completing the ritual!"); else if (random_range(100) > Player.iq+Player.pow+Player.level) mprint("Your concentration was broken -- the ritual fails!"); else { mprint("You charge the ritual with magical energy and focus your will."); mprint("Time Passes..."); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); RitualHour = hour(); /* set of random conditions for different ritual effects */ if (Current_Environment == E_CITY) { mprint("Flowing waves of mystical light congeal all around you."); mprint("'Like wow, man! Colors!'"); mprint("Appreciative citizens throw you spare change."); Player.cash +=random_range(50); } else if ( (roomno=Level->site[Player.x][Player.y].roomnumber) >= ROOMBASE ) { if (RitualRoom == roomno) mprint("For some reason the ritual doesn't work this time..."); else { RitualRoom = roomno; switch (RitualRoom) { case RS_TREASURE: /* ransacked treasure chamber */ mprint("Your spell sets off frenetic growth all around you!"); for(i=0;i<8;i++){ Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar = HEDGE; Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf = L_TRIFID; lset(Player.x+Dirs[0][i], Player.y+Dirs[1][i], CHANGED); } break; case RS_HAREM: /* harem */ case RS_BOUDOIR: /* boudoir */ mprint("A secret panel opens next to the bed...."); if (random_range(2)) summon(0,INCUBUS); /* succubus/incubus */ else summon(0,SATYR); /* satyr/nymph */ break; case RS_SHRINE: /*shrine to high magic */ mprint("A storm of mana coaelesces around you."); mprint("You are buffeted by bursts of random magic."); p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic"); mprint("Continue ritual? Could be dangerous.... [yn] "); if (ynq()=='y') s_wish(); else mprint("The mana fades away to nothingness."); x = Player.x; y = Player.y; while (x >= 0 && Level->site[x - 1][y].roomnumber == RS_SHRINE) x--; while (y >= 0 && Level->site[x][y - 1].roomnumber == RS_SHRINE) y--; for (i = 0; Level->site[x][y].roomnumber == RS_SHRINE;) { Level->site[x][y].roomnumber = RS_ZORCH; lset(x, y, CHANGED); x++; i++; if (Level->site[x][y].roomnumber != RS_SHRINE) { x -= i; i = 0; y++; } } break; case RS_MAGIC_LAB: /* magician's lab */ mprint("Your magical activity sets off a latent spell in the lab!"); cast_spell(random_range(NUMSPELLS)); break; case RS_PENTAGRAM: /* pentagram room */ mprint("A smoky form begins to coalesce...."); summon(-1,-1); mprint("Fortunately, it seems confined to the pentagram."); m_status_reset(Level->mlist->m,MOBILE); break; case RS_OMEGA_DAIS: /* blue omega room */ mprint("The Lords of Destiny look upon you...."); if (Player.level > 10) { mprint("A curtain of blue flames leaps up from the omega."); morewait(); l_adept(); } else { if (Player.patron == DESTINY) { mprint("Your patrons take pity on you."); if ((Player.rank[PRIESTHOOD]known = 2; symbol->charge = 17; gain_item(symbol); mprint("You feel uplifted."); } else gain_experience(min(1000,Player.xp)); } else if (random_range(3)==1) { mprint("You feel Fated."); gain_experience(Player.level*Player.level*10); Player.hp = max(Player.hp, Player.maxhp); } else if (random_range(2)) { mprint("You feel Doomed."); Player.hp = 1; Player.mana = 0; Player.xp = 0; } else mprint("The Lords of Destiny laugh at you!"); } break; default: mprint("Well, not much effect. Chalk it up to experience."); gain_experience(Player.level*5); break; } } } else { if (RitualRoom == Level->site[Player.x][Player.y].roomnumber) mprint("The ritual fails for some unexplainable reason."); else { mprint("The ritual seems to be generating some spell effect."); RitualRoom = Level->site[Player.x][Player.y].roomnumber; switch (RitualRoom) { case RS_WALLSPACE: shadowform(); break; case RS_CORRIDOR: haste(0); break; case RS_PONDS: breathe(0); break; case RS_ADEPT: hero(1); break; default: mprint("The ritual doesn't seem to produce any tangible results..."); gain_experience(Player.level*6); } } } } } void s_apport(void) { apport(0); } void s_shadowform(void) { shadowform(); } void s_alert(void) { alert(0); } void s_regenerate(void) { regenerate(0); } void s_clairvoyance(void) { clairvoyance(10); } void s_drain(void) { drain(0); } void s_levitate(void) { levitate(0); } void s_polymorph(void) { polymorph(0); } /* lball spell */ void s_lball(void) { int x=Player.x,y=Player.y; setspot(&x,&y); lball(Player.x,Player.y,x,y,Player.level*10+10); } void s_identify(void) { identify(0); } void s_objdet(void) { objdet(1); } void s_mondet(void) { mondet(1); } /* select a spell to cast */ int getspell(void) { int spell= ABORT - 1; do { mprint("Cast Spell: [type spell abbrev, ?, or ESCAPE]: "); spell = spellparse(); } while (spell < ABORT); return(spell); } char *spellid(int id) { switch(id) { case S_MON_DET:return("monster detection"); case S_OBJ_DET:return("object detection"); case S_IDENTIFY:return("identification"); case S_FIREBOLT:return("firebolt"); case S_LBALL:return("ball lightning"); case S_SLEEP:return("sleep"); case S_DISRUPT:return("disrupt"); case S_DISINTEGRATE:return("disintegrate"); case S_TELEPORT:return("teleport"); case S_MISSILE:return("magic missile"); case S_HEAL:return("healing"); case S_DISPEL:return("dispelling"); case S_BREATHE:return("breathing"); case S_INVISIBLE:return("invisibility"); case S_WARP:return("the warp"); case S_ENCHANT:return("enchantment"); case S_BLESS:return("blessing"); case S_RESTORE:return("restoration"); case S_CURE:return("curing"); case S_TRUESIGHT:return("true sight"); case S_HELLFIRE:return("hellfire"); case S_KNOWLEDGE:return("self knowledge"); case S_HERO:return("heroism"); case S_RETURN:return("return"); case S_DESECRATE:return("desecration"); case S_HASTE:return("haste"); case S_SUMMON:return("summoning"); case S_SANCTUARY:return("sanctuary"); case S_ACCURACY:return("accuracy"); case S_RITUAL:return("ritual magic"); case S_APPORT:return("apportation"); case S_SHADOWFORM:return("shadow form"); case S_ALERT:return("alertness"); case S_REGENERATE:return("regeneration"); case S_SANCTIFY:return("sanctification"); case S_CLAIRVOYANCE:return("clairvoyance"); case S_DRAIN:return("energy drain"); case S_LEVITATE:return("levitate"); case S_POLYMORPH:return("polymorph"); case S_FEAR:return("fear"); case S_WISH:return("wishing"); case S_NUTRITION:return("nutrition"); default:return("???"); } } void initspells(void) { int i; for (i=0; i 0) { prefix[--pos] = '\0'; byte = prefix[pos - 1]; f = first; while (f >= 0 && !strncmp(prefix, spell_names[f], pos)) { if (Spells[spell_ids[f]].known) first = f; f--; } l = last; while (l < NUMSPELLS && !strncmp(prefix, spell_names[l], pos)) { if (Spells[spell_ids[l]].known) last = l; l++; } if (found) found = 0; print2(prefix); } if (pos == 0) { first = 0; last = NUMSPELLS - 1; found = 0; print2(""); } } else if (byte == ESCAPE) { xredraw(); return ABORT; } else if (byte == '?') showknownspells(first, last); else if (byte != '\n') { if (byte >= 'A' && byte <= 'Z') byte += 'a' - 'A'; if (found) continue; f = first; l = last; while (f < NUMSPELLS && (!Spells[spell_ids[f]].known || strlen(spell_names[f]) < pos || spell_names[f][pos] < byte)) f++; while (l >= 0 && (!Spells[spell_ids[l]].known || strlen(spell_names[l]) < pos || spell_names[l][pos] > byte)) l--; if (l < f) continue; prefix[pos++] = byte; prefix[pos] = '\0'; nprint2(prefix + pos - 1); first = f; last = l; if (first == last && !found) { /* unique name */ found = 1; nprint2(spell_names[first] + pos); } } } while (byte != '\n'); xredraw(); if (found) return spell_ids[first]; else { print3("That is an ambiguous abbreviation!"); return ABORT; } }