876 lines
19 KiB
C
876 lines
19 KiB
C
/* 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]<SPRIEST) &&
|
|
(! find_item(&symbol,OB_SYMBOL_DESTINY,-1))) {
|
|
symbol = ((pob) checkmalloc(sizeof(objtype)));
|
|
*symbol = Objects[OB_SYMBOL_DESTINY];
|
|
symbol->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<NUMSPELLS; i++)
|
|
Spells[i].known = FALSE;
|
|
|
|
Spells[S_MON_DET].powerdrain = 3;
|
|
Spells[S_MON_DET].id = S_MON_DET;
|
|
|
|
Spells[S_OBJ_DET].powerdrain = 3;
|
|
Spells[S_OBJ_DET].id = S_OBJ_DET;
|
|
|
|
Spells[S_IDENTIFY].powerdrain = 10;
|
|
Spells[S_IDENTIFY].id = S_IDENTIFY;
|
|
|
|
Spells[S_FIREBOLT].powerdrain = 20;
|
|
Spells[S_FIREBOLT].id = S_FIREBOLT;
|
|
|
|
Spells[S_SLEEP].powerdrain = 15;
|
|
Spells[S_SLEEP].id = S_SLEEP;
|
|
|
|
Spells[S_LBALL].powerdrain = 25;
|
|
Spells[S_LBALL].id = S_LBALL;
|
|
|
|
Spells[S_TELEPORT].powerdrain = 20;
|
|
Spells[S_TELEPORT].id = S_TELEPORT;
|
|
|
|
Spells[S_DISRUPT].powerdrain = 30;
|
|
Spells[S_DISRUPT].id = S_DISRUPT;
|
|
|
|
Spells[S_DISINTEGRATE].powerdrain = 40;
|
|
Spells[S_DISINTEGRATE].id = S_DISINTEGRATE;
|
|
|
|
Spells[S_MISSILE].powerdrain = 10;
|
|
Spells[S_MISSILE].id = S_MISSILE;
|
|
|
|
Spells[S_HEAL].powerdrain = 15;
|
|
Spells[S_HEAL].id = S_HEAL;
|
|
|
|
Spells[S_DISPEL].powerdrain = 40;
|
|
Spells[S_DISPEL].id = S_DISPEL;
|
|
|
|
Spells[S_BREATHE].powerdrain = 20;
|
|
Spells[S_BREATHE].id = S_BREATHE;
|
|
|
|
Spells[S_INVISIBLE].powerdrain = 15;
|
|
Spells[S_INVISIBLE].id = S_INVISIBLE;
|
|
|
|
Spells[S_WARP].powerdrain = 50;
|
|
Spells[S_WARP].id = S_WARP;
|
|
|
|
Spells[S_ENCHANT].powerdrain = 30;
|
|
Spells[S_ENCHANT].id = S_ENCHANT;
|
|
|
|
Spells[S_BLESS].powerdrain = 30;
|
|
Spells[S_BLESS].id = S_BLESS;
|
|
|
|
Spells[S_RESTORE].powerdrain = 20;
|
|
Spells[S_RESTORE].id = S_RESTORE;
|
|
|
|
Spells[S_CURE].powerdrain = 20;
|
|
Spells[S_CURE].id = S_CURE;
|
|
|
|
Spells[S_TRUESIGHT].powerdrain = 20;
|
|
Spells[S_TRUESIGHT].id = S_TRUESIGHT;
|
|
|
|
Spells[S_HELLFIRE].powerdrain = 90;
|
|
Spells[S_HELLFIRE].id = S_HELLFIRE;
|
|
|
|
Spells[S_KNOWLEDGE].powerdrain = 10;
|
|
Spells[S_KNOWLEDGE].id = S_KNOWLEDGE;
|
|
|
|
Spells[S_HERO].powerdrain = 20;
|
|
Spells[S_HERO].id = S_HERO;
|
|
|
|
Spells[S_RETURN].powerdrain = 10;
|
|
Spells[S_RETURN].id = S_RETURN;
|
|
|
|
Spells[S_DESECRATE].powerdrain = 50;
|
|
Spells[S_DESECRATE].id = S_DESECRATE;
|
|
|
|
Spells[S_HASTE].powerdrain = 15;
|
|
Spells[S_HASTE].id = S_HASTE;
|
|
|
|
Spells[S_SUMMON].powerdrain = 20;
|
|
Spells[S_SUMMON].id = S_SUMMON;
|
|
|
|
Spells[S_SANCTUARY].powerdrain = 75;
|
|
Spells[S_SANCTUARY].id = S_SANCTUARY;
|
|
|
|
Spells[S_ACCURACY].powerdrain = 20;
|
|
Spells[S_ACCURACY].id = S_ACCURACY;
|
|
|
|
Spells[S_RITUAL].powerdrain = 50;
|
|
Spells[S_RITUAL].id = S_RITUAL;
|
|
|
|
Spells[S_APPORT].powerdrain = 15;
|
|
Spells[S_APPORT].id = S_APPORT;
|
|
|
|
Spells[S_SHADOWFORM].powerdrain = 50;
|
|
Spells[S_SHADOWFORM].id = S_SHADOWFORM;
|
|
|
|
Spells[S_ALERT].powerdrain = 15;
|
|
Spells[S_ALERT].id = S_ALERT;
|
|
|
|
Spells[S_REGENERATE].powerdrain = 20;
|
|
Spells[S_REGENERATE].id = S_REGENERATE;
|
|
|
|
Spells[S_SANCTIFY].powerdrain = 75;
|
|
Spells[S_SANCTIFY].id = S_SANCTIFY;
|
|
|
|
Spells[S_CLAIRVOYANCE].powerdrain = 10;
|
|
Spells[S_CLAIRVOYANCE].id = S_CLAIRVOYANCE;
|
|
|
|
Spells[S_DRAIN].powerdrain = 40;
|
|
Spells[S_DRAIN].id = S_DRAIN;
|
|
|
|
Spells[S_LEVITATE].powerdrain = 25;
|
|
Spells[S_LEVITATE].id = S_LEVITATE;
|
|
|
|
Spells[S_POLYMORPH].powerdrain = 30;
|
|
Spells[S_POLYMORPH].id = S_POLYMORPH;
|
|
|
|
Spells[S_FEAR].powerdrain = 10;
|
|
Spells[S_FEAR].id = S_FEAR;
|
|
|
|
Spells[S_WISH].powerdrain = 100;
|
|
Spells[S_WISH].id = S_WISH;
|
|
|
|
Spells[S_NUTRITION].powerdrain = 25;
|
|
Spells[S_NUTRITION].id = S_NUTRITION;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cast_spell(int spell)
|
|
{
|
|
switch(spell) {
|
|
case S_MON_DET:s_mondet();
|
|
break;
|
|
case S_OBJ_DET:s_objdet();
|
|
break;
|
|
case S_IDENTIFY:s_identify();
|
|
break;
|
|
case S_FIREBOLT:s_firebolt();
|
|
break;
|
|
case S_SLEEP:s_sleep();
|
|
break;
|
|
case S_LBALL:s_lball();
|
|
break;
|
|
case S_TELEPORT:s_teleport();
|
|
break;
|
|
case S_DISRUPT:s_disrupt();
|
|
break;
|
|
case S_DISINTEGRATE:s_disintegrate();
|
|
break;
|
|
case S_MISSILE:s_missile();
|
|
break;
|
|
case S_HEAL:s_heal();
|
|
break;
|
|
case S_DISPEL:s_dispel();
|
|
break;
|
|
case S_BREATHE:s_breathe();
|
|
break;
|
|
case S_INVISIBLE:s_invisible();
|
|
break;
|
|
case S_WARP:s_warp();
|
|
break;
|
|
case S_ENCHANT:s_enchant();
|
|
break;
|
|
case S_BLESS:s_bless();
|
|
break;
|
|
case S_RESTORE:s_restore();
|
|
break;
|
|
case S_CURE:s_cure();
|
|
break;
|
|
case S_TRUESIGHT:s_truesight();
|
|
break;
|
|
case S_HELLFIRE:s_hellfire();
|
|
break;
|
|
case S_KNOWLEDGE:s_knowledge();
|
|
break;
|
|
case S_HERO:s_hero();
|
|
break;
|
|
case S_RETURN:s_return();
|
|
break;
|
|
case S_DESECRATE:s_desecrate();
|
|
break;
|
|
case S_HASTE:s_haste();
|
|
break;
|
|
case S_SUMMON:s_summon();
|
|
break;
|
|
case S_SANCTUARY:s_sanctuary();
|
|
break;
|
|
case S_ACCURACY:s_accuracy();
|
|
break;
|
|
case S_RITUAL:s_ritual();
|
|
break;
|
|
case S_APPORT:s_apport();
|
|
break;
|
|
case S_SHADOWFORM:s_shadowform();
|
|
break;
|
|
case S_ALERT:s_alert();
|
|
break;
|
|
case S_REGENERATE:s_regenerate();
|
|
break;
|
|
case S_SANCTIFY:s_sanctify();
|
|
break;
|
|
case S_CLAIRVOYANCE:s_clairvoyance();
|
|
break;
|
|
case S_DRAIN:s_drain();
|
|
break;
|
|
case S_LEVITATE:s_levitate();
|
|
break;
|
|
case S_FEAR:s_fear();
|
|
break;
|
|
case S_POLYMORPH:s_polymorph();
|
|
break;
|
|
case S_WISH:s_wish();
|
|
break;
|
|
case S_NUTRITION:s_nutrition();
|
|
break;
|
|
default: mprint("Your odd spell fizzles with a small 'sput'.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static char *spell_names[] = { /* alphabetical listing */
|
|
"accuracy", "alertness", "apportation", "ball lightning", "blessing",
|
|
"breathing", "clairvoyance", "curing", "desecration", "disintegrate",
|
|
"dispelling", "disrupt", "enchantment", "energy drain", "fear", "firebolt",
|
|
"haste", "healing", "hellfire", "heroism", "identification", "invisibility",
|
|
"levitate", "magic missile", "monster detection", "nutrition", "object detection",
|
|
"polymorph", "regeneration", "restoration", "return", "ritual magic",
|
|
"sanctification", "sanctuary", "self knowledge", "shadow form", "sleep",
|
|
"summoning", "teleport", "the warp", "true sight", "wishing" };
|
|
|
|
static int spell_ids[] = { /* in the same order as spell_names[] */
|
|
S_ACCURACY, S_ALERT, S_APPORT, S_LBALL, S_BLESS, S_BREATHE, S_CLAIRVOYANCE,
|
|
S_CURE, S_DESECRATE, S_DISINTEGRATE, S_DISPEL, S_DISRUPT, S_ENCHANT, S_DRAIN,
|
|
S_FEAR, S_FIREBOLT, S_HASTE, S_HEAL, S_HELLFIRE, S_HERO, S_IDENTIFY,
|
|
S_INVISIBLE, S_LEVITATE, S_MISSILE, S_MON_DET, S_NUTRITION, S_OBJ_DET, S_POLYMORPH,
|
|
S_REGENERATE, S_RESTORE, S_RETURN, S_RITUAL, S_SANCTIFY, S_SANCTUARY,
|
|
S_KNOWLEDGE, S_SHADOWFORM, S_SLEEP, S_SUMMON, S_TELEPORT, S_WARP, S_TRUESIGHT,
|
|
S_WISH };
|
|
|
|
void showknownspells(int first, int last)
|
|
{
|
|
int i,printed=FALSE;
|
|
|
|
menuclear();
|
|
menuprint("\nPossible Spells:\n");
|
|
for (i = first; i <= last; i++)
|
|
if (Spells[spell_ids[i]].known) {
|
|
printed = TRUE;
|
|
menuprint(spell_names[i]);
|
|
menuprint(" (");
|
|
menunumprint(Spells[spell_ids[i]].powerdrain);
|
|
menuprint(" mana)");
|
|
menuprint("\n");
|
|
}
|
|
if (! printed)
|
|
menuprint("\nNo spells match that prefix!");
|
|
showmenu();
|
|
}
|
|
|
|
int spellparse(void)
|
|
{
|
|
int first, last, pos;
|
|
char byte, prefix[80];
|
|
int found = 0;
|
|
int f, l;
|
|
|
|
first = 0;
|
|
while (first < NUMSPELLS && !Spells[spell_ids[first]].known)
|
|
first++;
|
|
if (first == NUMSPELLS) {
|
|
print1("You don't know any spells!");
|
|
return ABORT;
|
|
}
|
|
last = NUMSPELLS - 1;
|
|
pos = 0;
|
|
print2("");
|
|
do {
|
|
byte = mgetc();
|
|
if (byte == BACKSPACE || byte == DELETE) {
|
|
if (pos > 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;
|
|
}
|
|
}
|