/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ /* effect1.c */ #include "glob.h" /* enchant */ void enchant(int delta) { int i,used = FALSE; long change_cash; if (delta < 0) { i = random_item(); if (i == ABORT || Player.possessions[i]->usef == I_NOTHING || Player.possessions[i]->usef == I_NO_OP || Player.possessions[i]->usef == I_NORMAL_ARMOR || Player.possessions[i]->usef == I_NORMAL_WEAPON || Player.possessions[i]->usef == I_NORMAL_SHIELD || Player.possessions[i]->objchar == FOOD || Player.possessions[i]->objchar == MISSILEWEAPON) { print1("You feel fortunate."); morewait(); } else if (Player.possessions[i]->blessing < 0 || (Player.possessions[i]->objchar == ARTIFACT && random_range(3))) { if (Player.possessions[i]->uniqueness == COMMON) print1("Your "); nprint1(itemid(Player.possessions[i])); nprint1(" glows, but the glow flickers out..."); morewait(); } else { used = (Player.possessions[i]->used); if (used) { Player.possessions[i]->used = FALSE; item_use(Player.possessions[i]); } if (Player.possessions[i]->uniqueness == COMMON) print1("Your "); nprint1(itemid(Player.possessions[i])); nprint1(" radiates an aura of mundanity!"); morewait(); Player.possessions[i]->plus = 0; Player.possessions[i]->charge = -1; Player.possessions[i]->usef = I_NOTHING; if (used) { Player.possessions[i]->used = TRUE; item_use(Player.possessions[i]); } } } else { i = getitem(CASH); if (i == ABORT) { print1("You feel unlucky."); morewait(); } else if (i == CASHVALUE) { print1("You enchant your money.... What a concept!"); change_cash = Player.cash*(random_range(7) - 3)/6; if (change_cash > 0) print2("Seems to have been a good idea!"); else print2("Maybe it wasn't such a good idea...."); Player.cash += change_cash; morewait(); } else if (Player.possessions[i]->objchar == ARTIFACT) { if (Player.possessions[i]->usef != Objects[Player.possessions[i]->id].usef) { print1("It re-acquires its magical aura!"); Player.possessions[i]->usef = Objects[Player.possessions[i]->id].usef; } else { print1("The enchantment spell enfolds the "); nprint1(itemid(Player.possessions[i])); print2("and the potent enchantment of the Artifact causes a backlash!"); morewait(); clearmsg(); manastorm(Player.x,Player.y,Player.possessions[i]->level*5); } } else { if (Player.possessions[i]->plus > random_range(20)+1) { print1("Uh-oh, the force of the enchantment was too much!"); print2("There is a loud explosion!"); morewait(); manastorm(Player.x,Player.y,Player.possessions[i]->plus*5); dispose_lost_objects(1,Player.possessions[i]); } else { used = (Player.possessions[i]->used); if (used) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[i]->used = FALSE; item_use(Player.possessions[i]); resetgamestatus(SUPPRESS_PRINTING); } print1("The item shines!"); morewait(); Player.possessions[i]->plus += delta+1; if (Player.possessions[i]->charge > -1) Player.possessions[i]->charge += ((delta+1) * (random_range(10) + 1)); if (used) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[i]->used = TRUE; item_use(Player.possessions[i]); resetgamestatus(SUPPRESS_PRINTING); } } } calc_melee(); } } /* bless */ void bless(int blessing) { int index,used; if (blessing < 0) { index = random_item(); if (index == ABORT) { print1("You feel fortunate."); morewait(); } else { print1("A foul odor arises from "); if (Player.possessions[index]->uniqueness == COMMON) nprint1("your "); nprint1(itemid(Player.possessions[index])); morewait(); used = (Player.possessions[index]->used); if (used) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[index]->used = FALSE; item_use(Player.possessions[index]); resetgamestatus(SUPPRESS_PRINTING); } Player.possessions[index]->blessing -= 2; if (Player.possessions[index]->blessing < 0) Player.possessions[index]->plus = abs(Player.possessions[index]->plus) - 1; if (used) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[index]->used = TRUE; item_use(Player.possessions[index]); resetgamestatus(SUPPRESS_PRINTING); } } } else { index = getitem(NULL_ITEM); if (index == CASHVALUE) { print1("Blessing your money has no effect."); morewait(); } else if (index != ABORT) { used = (Player.possessions[index]->used == TRUE); if (used) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[index]->used = FALSE; item_use(Player.possessions[index]); resetgamestatus(SUPPRESS_PRINTING); } print1("A pure white light surrounds the item... "); if (Player.possessions[index]->blessing < 0-(blessing+1)) { print2("which is evil enough to resist the effect of the blessing!"); morewait(); } else if (Player.possessions[index]->blessing < -1) { print2("which disintegrates under the influence of the holy aura!"); morewait(); Player.itemweight -= Player.possessions[index]->weight; dispose_lost_objects(1,Player.possessions[index]); } else if (Player.possessions[index]->blessing < blessing+1) { print2("which now seems affected by afflatus!"); morewait(); Player.possessions[index]->blessing++; Player.possessions[index]->plus = abs(Player.possessions[index]->plus)+1; } else { print2("The hierolux fades without any appreciable effect...."); morewait(); } if (used && (Player.possessions[index] != NULL)) { setgamestatus(SUPPRESS_PRINTING); Player.possessions[index]->used = TRUE; item_use(Player.possessions[index]); resetgamestatus(SUPPRESS_PRINTING); } } } calc_melee(); } void heal(int amount) { if (amount > -1) { mprint("You feel better."); if (Player.hp < Player.maxhp + amount) { Player.hp += random_range(10*amount)+1; if (Player.hp > Player.maxhp) Player.hp = Player.maxhp + amount; } Player.status[BLINDED] = 0; } else { mprint("You feel unwell."); Player.hp -= random_range(10*abs(amount)+1); if (Player.hp < 0) p_death("magical disruption"); } dataprint(); } void fbolt(int fx, int fy, int tx, int ty, int hit, int dmg) { bolt(fx,fy,tx,ty,hit,dmg,FLAME); } void lbolt(int fx, int fy, int tx, int ty, int hit, int dmg) { bolt(fx,fy,tx,ty,hit,dmg,ELECTRICITY); } /* Added 12/30/98 DG */ void icebolt(int fx, int fy, int tx, int ty, int hit, int dmg) { bolt(fx,fy,tx,ty,hit,dmg,COLD); } void nbolt(int fx, int fy, int tx, int ty, int hit, int dmg) { bolt(fx,fy,tx,ty,hit,dmg,NORMAL_DAMAGE); } /* from f to t */ void bolt(int fx, int fy, int tx, int ty, int hit, int dmg, int dtype) { int xx,yy; struct monster *target; Symbol boltchar = '?'; xx = fx; yy = fy; switch(dtype) { case FLAME:boltchar=('*' | CLR(LIGHT_RED));break; case ELECTRICITY:boltchar = ('^' | CLR(LIGHT_BLUE));break; case NORMAL_DAMAGE:boltchar = ('!' | CLR(BROWN));break; case COLD:boltchar=('o' | CLR(WHITE));break; default:assert(FALSE); /* this should never happen, right? WDT */ } clearmsg(); do_los(boltchar,&xx,&yy,tx,ty); if ((xx == Player.x) && (yy == Player.y)) { if (Player.status[DEFLECTION] > 0) mprint("The bolt just missed you!"); else { switch (dtype) { case FLAME: mprint("You were blasted by a firebolt!"); p_damage(random_range(dmg),dtype,"a firebolt"); break; case ELECTRICITY: mprint("You were zapped by lightning!"); p_damage(random_range(dmg),dtype,"a bolt of lightning"); break; case NORMAL_DAMAGE: mprint("You were hit by a missile!"); p_damage(random_range(dmg),dtype,"a missile"); break; case COLD: mprint("You were hit by an icicle!"); p_damage(random_range(dmg),dtype,"an icicle"); break; } } } else if (NULL != (target = Level->site[xx][yy].creature)) { if (hitp(hit,target->ac)) { if (target->uniqueness == COMMON) { strcpy(Str1,"The "); strcat(Str1,target->monstring); } else strcpy(Str1,target->monstring); switch (dtype) { /* WDT: these sentances really ought to be livened up. Especially * in full verbose mode. */ case FLAME:strcat(Str1," was blasted by a firebolt!");break; case ELECTRICITY:strcat(Str1," was zapped by lightning!");break; case NORMAL_DAMAGE:strcat(Str1," was hit by a missile!"); break; case COLD:strcat(Str1," was hit by an icicle!"); break; } mprint(Str1); m_status_set(target,HOSTILE); m_damage(target,random_range(dmg),dtype); } else { if (target->uniqueness == COMMON) { strcpy(Str1,"The "); strcat(Str1,target->monstring); } else strcpy(Str1,target->monstring); switch (dtype) { case FLAME:strcat(Str1," was missed by a firebolt!");break; case ELECTRICITY:strcat(Str1," was missed by lightning!");break; case NORMAL_DAMAGE:strcat(Str1," was missed by a missile!"); break; case COLD:strcat(Str1," was missed by a flying icicle!"); break; } mprint(Str1); } } else if (Level->site[xx][yy].locchar == HEDGE) if (Level->site[xx][yy].p_locf != L_TRIFID) { if ((dtype == FLAME)||(dtype == ELECTRICITY)) { mprint("The hedge is blasted away!"); Level->site[xx][yy].p_locf = L_NO_OP; Level->site[xx][yy].locchar = FLOOR; plotspot(xx, yy, TRUE); lset(xx, yy, CHANGED); } else mprint("The hedge is unaffected."); } else mprint("The trifid absorbs the energy and laughs!"); else if (Level->site[xx][yy].locchar == WATER) if (dtype == FLAME) { mprint("The water is vaporised!"); Level->site[xx][yy].p_locf = L_NO_OP; Level->site[xx][yy].locchar = FLOOR; lset(xx, yy, CHANGED); } } void lball(int fx, int fy, int tx, int ty, int dmg) { ball(fx,fy,tx,ty,dmg,ELECTRICITY); } void manastorm(int x, int y, int dmg) { ball(x,y,x,y,dmg,UNSTOPPABLE); } void snowball(int fx, int fy, int tx, int ty, int dmg) { ball(fx,fy,tx,ty,dmg,COLD); } void fball(int fx, int fy, int tx, int ty, int dmg) { ball(fx,fy,tx,ty,dmg,FLAME); } /* from f to t */ void ball(int fx, int fy, int tx, int ty, int dmg, int dtype) { int xx,yy,ex,ey,i; struct monster *target; Symbol expchar=('@' | CLR(LIGHT_PURPLE)); xx = fx; yy = fy; switch(dtype){ case FLAME:expchar=('*' | CLR(LIGHT_RED));break; case COLD:expchar=('o' | CLR(WHITE));break; case ELECTRICITY:expchar=('^' | CLR(LIGHT_BLUE));break; } do_los(expchar,&xx,&yy,tx,ty); draw_explosion(expchar,xx,yy); for(i=0;i<9;i++) { ex = xx + Dirs[0][i]; ey = yy + Dirs[1][i]; if ((ex == Player.x) && (ey == Player.y)) { switch(dtype) { case FLAME:mprint("You were blasted by a fireball!"); p_damage(random_range(dmg),FLAME,"a fireball"); break; case COLD:mprint("You were blasted by a snowball!"); p_damage(random_range(dmg),COLD,"a snowball"); break; case ELECTRICITY:mprint("You were blasted by ball lightning!"); p_damage(random_range(dmg),ELECTRICITY,"ball lightning"); break; case UNSTOPPABLE:mprint("Oh No! Manastorm!"); p_damage(random_range(dmg),UNSTOPPABLE,"a manastorm!"); break; } } if (NULL != (target = Level->site[ex][ey].creature)) { if (los_p(Player.x,Player.y,target->x,target->y)) { if (target->uniqueness == COMMON) { strcpy(Str1,"The "); strcat(Str1,target->monstring); } else strcpy(Str1,target->monstring); switch(dtype) { case FLAME:strcat(Str1," was zorched by a fireball!"); break; case COLD:strcat(Str1," was blasted by a snowball!"); break; case ELECTRICITY:strcat(Str1," was zapped by ball lightning!");break; case UNSTOPPABLE:strcat(Str1," was nuked by a manastorm!");break; } mprint(Str1); } m_status_set(target,HOSTILE); m_damage(target,random_range(dmg),dtype); } if (Level->site[ex][ey].locchar == HEDGE) if (Level->site[ex][ey].p_locf != L_TRIFID) { if ((dtype == FLAME)||(dtype == ELECTRICITY)) { mprint("The hedge is blasted away!"); Level->site[ex][ey].p_locf = L_NO_OP; Level->site[ex][ey].locchar = FLOOR; plotspot(ex,ey,TRUE); lset(ex, ey, CHANGED); } else mprint("The hedge is unaffected."); } else mprint("The trifid absorbs the energy and laughs!"); else if (Level->site[ex][ey].locchar == WATER) if (dtype == FLAME) { mprint("The water is vaporised!"); Level->site[ex][ey].p_locf = L_NO_OP; Level->site[ex][ey].locchar = FLOOR; plotspot(ex,ey,TRUE); lset(ex, ey, CHANGED); } } } void mondet(int blessing) { pml ml; for (ml=Level->mlist;ml!=NULL;ml=ml->next) if (ml->m->hp > 0) /* FIXED 12/30/98 DG */ { if (blessing > -1) plotmon(ml->m); else putspot(random_range(Level->level_width), random_range(Level->level_length), Monsters[random_range(NUMMONSTERS)].monchar); } levelrefresh(); morewait(); show_screen(); } void objdet(int blessing) { int i,j; for (i=0;ilevel_width;i++) for (j=0;jlevel_length;j++) if (Level->site[i][j].things != NULL) { if (blessing < 0) putspot(random_range(Level->level_width), random_range(Level->level_length), Level->site[i][j].things->thing->objchar); else putspot(i,j,Level->site[i][j].things->thing->objchar); } levelrefresh(); morewait(); show_screen(); } void identify(int blessing) { int index; clearmsg(); if (blessing == 0) { index = getitem_prompt("Identify: ", NULL_ITEM); if (index == CASHVALUE) print3("Your money is really money."); else if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { if (Player.possessions[index]->objchar == FOOD) Player.possessions[index]->known = 1; else { Player.possessions[index]->known = 2; Objects[Player.possessions[index]->id].known = 1; } print1("Identified: "); mprint(itemid(Player.possessions[index])); } } else if (blessing < 0) { print2("You feel forgetful."); for (index=0;indexknown = 0; Objects[Player.possessions[index]->id].known = 0; } } else { print2("You feel encyclopaedic."); for (index=0;indexobjchar == FOOD) Player.possessions[index]->known = 1; else { Player.possessions[index]->known = 2; Objects[Player.possessions[index]->id].known = 1; } } for (index=0;indexobjchar == FOOD) Player.pack[index]->known = 1; else { Player.pack[index]->known = 2; Objects[Player.pack[index]->id].known = 1; } } } calc_melee(); } /* returns index of random item, ABORT if player carrying none */ int random_item(void) { int item = ABORT,tries=0; int number = 0; for(tries=0; triesid < OB_DEBIT_CARD) continue; if (Player.possessions[idx]->id > OB_SMART_CARD) continue; cards[nextitem++] = idx; } if (0 == nextitem) return random_item(); if (nextitem > 1) shuffle(cards, nextitem); if (random_range(100) < 75) { /* oh that sucks... */ return cards[0]; } return random_item(); } /* various kinds of wishes */ void wish(int blessing) { int i; char wishstr[80]; clearmsg(); print1("What do you wish for? "); if (blessing < 0) deathprint(); else strcpy(wishstr,msgscanstring()); if (blessing < 0 || strcmp(wishstr,"Death")==0) { print2("As you wish, so shall it be."); p_death("a deathwish"); } if (strcmp(wishstr,"Power")==0) { print2("You feel a sudden surge of energy"); Player.mana=calcmana()*10; } else if (strcmp(wishstr,"Skill")==0) { print2("You feel more competent."); if (gamestatusp(CHEATED)) gain_experience(10000); else gain_experience(min(10000,Player.xp)); } else if (strcmp(wishstr,"Wealth")==0) { print2("You are submerged in shower of gold pieces!"); Player.cash += 10000; } else if (strcmp(wishstr,"Balance")==0) { print2("You feel neutral."); Player.alignment = 0; } else if (strcmp(wishstr,"Chaos")==0) { print2("You feel chaotic."); Player.alignment -= 25; } else if (strcmp(wishstr,"Law")==0) { print2("You feel lawful."); Player.alignment += 25; } else if (strcmp(wishstr,"Location")==0) strategic_teleport(1); else if (strcmp(wishstr,"Knowledge")==0) { print2("You feel more knowledgeable."); i = random_range(NUMSPELLS); if (Spells[i].known) Spells[i].powerdrain = (max(1,Spells[i].powerdrain/2)); else Spells[i].known = TRUE; } else if (strcmp(wishstr,"Health")==0) { print2("You feel vigorous"); Player.hp = max( Player.hp, Player.maxhp); Player.status[DISEASED] = 0; Player.status[POISONED] = 0; Player.food = 43; /* Wish for Health when starving does some good. PGM */ } else if (strcmp(wishstr,"Destruction")==0) annihilate(gamestatusp(CHEATED)); else if (strcmp(wishstr,"Acquisition")==0) acquire(gamestatusp(CHEATED)); else if (strcmp(wishstr,"Summoning")==0) summon(gamestatusp(CHEATED),-1); else if (strcmp(wishstr,"Stats") == 0 && gamestatusp(CHEATED)) { Player.str = Player.maxstr = Player.con = Player.maxcon = Player.agi = Player.maxagi = Player.dex = Player.maxdex = Player.iq = Player.maxiq = Player.pow = Player.maxpow = 200; calc_melee(); } else print2("You feel stupid."); dataprint(); showflags(); } /* gain for an item */ void acquire(int blessing) { char otype; int index,id = ABORT; pob newthing; if (blessing < 0) { index = random_item(); if (index == ABORT) mprint("You feel fortunate."); else { print1("Smoke drifts out of your pack.... "); print2("Destroyed: "); nprint2(itemid(Player.possessions[index])); morewait(); dispose_lost_objects(1,Player.possessions[index]); } } else { newthing = ((pob) checkmalloc(sizeof(objtype))); /* DAG this assignment looks unneccessary */ newthing->id = -1; if (gamestatusp(CHEATED)) print1("Acquire which kind of item: !?][}{)/=%%\\& "); else print1("Acquire which kind of item: !?][}{)/=%%\\ "); otype = mgetc(); switch (otype) { case (POTION&0xff): if (blessing > 0) id = itemlist(POTIONID,NUMPOTIONS); else id = random_range(NUMPOTIONS); if (id < 0) print2("You feel stupid."); else make_potion(newthing,id); break; case (SCROLL&0xff): if (blessing > 0) id = itemlist(SCROLLID,NUMSCROLLS); else id = random_range(NUMSCROLLS); if (id < 0) print2("You feel stupid."); else make_scroll(newthing,id); break; case (RING&0xff): if (blessing > 0) id = itemlist(RINGID,NUMRINGS); else id = random_range(NUMRINGS); if (id < 0) print2("You feel stupid."); else make_ring(newthing,id); break; case (STICK&0xff): if (blessing > 0) id = itemlist(STICKID,NUMSTICKS); else id = random_range(NUMSTICKS); if (id < 0) print2("You feel stupid."); else make_stick(newthing,id); break; case (ARMOR&0xff): if (blessing > 0) id = itemlist(ARMORID,NUMARMOR); else id = random_range(NUMARMOR); if (id < 0) print2("You feel stupid."); else make_armor(newthing,id); break; case (SHIELD&0xff): if (blessing > 0) id = itemlist(SHIELDID,NUMSHIELDS); else id = random_range(NUMSHIELDS); if (id < 0) print2("You feel stupid."); else make_shield(newthing,id); break; case (WEAPON&0xff): if (blessing > 0) id = itemlist(WEAPONID,NUMWEAPONS); else id = random_range(NUMWEAPONS); if (id < 0) print2("You feel stupid."); else make_weapon(newthing,id); break; case (BOOTS&0xff): if (blessing > 0) id = itemlist(BOOTID,NUMBOOTS); else id = random_range(NUMBOOTS); if (id < 0) print2("You feel stupid."); else make_boots(newthing,id); break; case (CLOAK&0xff): if (blessing > 0) id = itemlist(CLOAKID,NUMCLOAKS); else id = random_range(NUMCLOAKS); if (id < 0) print2("You feel stupid."); else make_cloak(newthing,id); break; case (FOOD&0xff): if (blessing > 0) id = itemlist(FOODID,NUMFOODS); else id = random_range(NUMFOODS); if (id < 0) print2("You feel stupid."); else make_food(newthing,id); break; case (THING&0xff): if (blessing > 0) id = itemlist(THINGID,NUMTHINGS); else id = random_range(NUMTHINGS); if (id < 0) print2("You feel stupid."); else make_thing(newthing,id); break; case (ARTIFACT&0xff): if (gamestatusp(CHEATED)) id = itemlist(ARTIFACTID,NUMARTIFACTS); else id = -1; if (id < 0) print2("You feel stupid."); else make_artifact(newthing,id); break; default: print2("You feel stupid."); } xredraw(); if (id != ABORT) { if (blessing > 0) { newthing->known = 2; Objects[id].known = 1; } newthing->used = FALSE; gain_item(newthing); } else { /* DAG newthing allocated but was not freed... was YA memory leak */ /* use free() rather than free_obj() since newthing not initialized */ free( (char *) newthing ); } } }