void draw_explosion(Symbol pyx, int x, int y) { int i,j; for(j=0;j<3;j++) { for(i=0;i<9;i++) plotchar(pyx,x+Dirs[0][i],y+Dirs[1][i]); usleep(150000); for(i=0;i<9;i++) plotchar(SPACE,x+Dirs[0][i],y+Dirs[1][i]); usleep(150000); } for(i=0;i<9;i++) plotspot(x+Dirs[0][i],y+Dirs[1][i],TRUE); wrefresh(Levelw); }
void drawplayer(void) { int c; if (E_COUNTRYSIDE == Current_Environment) { if (inbounds(lastx, lasty) && !offscreen(lastx, lasty)) { wmove(Levelw, screenmody(lasty), screenmodx(lastx)); c = Country[lastx][lasty].current_terrain_type; if (optionp(SHOW_COLOUR)) wattrset(Levelw, CHARATTR(c)); waddch(Levelw, c & 0xff); } wmove(Levelw, screenmody(Player.y), screenmodx(Player.x)); if (optionp(SHOW_COLOUR)) wattrset(Levelw, CHARATTR(PLAYER)); waddch(Levelw, PLAYER & 0xff); } else { if (inbounds(lastx, lasty) && !offscreen(lastx, lasty)) plotspot(lastx, lasty, (Player.status[BLINDED] > 0 ? FALSE : TRUE)); wmove(Levelw, screenmody(Player.y), screenmodx(Player.x)); if ((!Player.status[INVISIBLE]) || Player.status[TRUESIGHT]) { if (optionp(SHOW_COLOUR)) wattrset(Levelw, CHARATTR(PLAYER)); waddch(Levelw, PLAYER & 0xff); } } lastx = Player.x; lasty = Player.y; }
void m_blind_strike(pmt m) { pml ml; if ((Player.status[BLINDED] == 0) && los_p(m->x,m->y,Player.x,Player.y) && (distance(m->x,m->y,Player.x,Player.y) < 5)) { if (m->uniqueness == COMMON) { strcpy(Str2,"The "); strcat(Str2,m->monstring); } else strcpy(Str2,m->monstring); strcat(Str2," gazes at you menacingly"); mprint(Str2); if (! p_immune(GAZE)) { mprint("You've been blinded!"); Player.status[BLINDED] = random_range(4)+1; for(ml=Level->mlist;ml!=NULL;ml=ml->next) plotspot(ml->m->x,ml->m->y,FALSE); } else mprint("You gaze steadily back...."); } }
/* from f to t */ void ball(int fx, int fy, int tx, int ty, int dmg, int dtype) { int xx,yy,ex,ey,i; 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->name); } else strcpy(Str1,target->name); 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); target->m_damage(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); } } }
/* from f to t */ void bolt(int fx, int fy, int tx, int ty, int hit, int dmg, int dtype) { int xx,yy; 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->name); } else strcpy(Str1,target->name); 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); target->m_damage(random_range(dmg),dtype); } else { if (target->uniqueness == COMMON) { strcpy(Str1,"The "); strcat(Str1,target->name); } else strcpy(Str1,target->name); 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 m_death(struct monster *m) { pob corpse; pml ml; int x; int y; int found = FALSE; m->hp = -1; if(los_p(Player.x, Player.y, m->x, m->y)) { putspot(m->x, m->y, getspot(m->x, m->y, FALSE)); gain_experience(m->xpv); calc_melee(); if(m->uniqueness != COMMON) { strcpy(Str1, m->monstring); } else { strcpy(Str1, "The "); strcat(Str1, m->monstring); } strcat(Str1, " is dead!"); mprint(Str1); } m_dropstuff(m); /* Death */ if(m->id == (ML10 + 0)) { mprint("Death lies sprawled out on the ground..."); mprint("Death laughs ironically and gets back to his feet."); mprint("He gestures and another scythe appears in his hands."); switch(random_range(10)) { case 0: mprint("Death performs a little bow and goes back on guard."); break; case 1: mprint("\'A hit! A palpable hit!\' Death goes back on the attack."); break; case 2: mprint("\'Ah, if only it could be so simple!\' snickers Death."); break; case 3: mprint("\'This fool things he can slay death! What a jest!\' says Death."); break; case 4: mprint("\'You point is well taken.\' says Death, attacking again."); break; case 5: mprint("\'Oh, come now, stop delaying the inevitable.\' says Death."); break; case 6: mprint("\'Your destiny ends here with me.\' says Death, scythe raised."); break; case 7: mprint("\'I almost felt that.\' says Death, smiling."); break; case 8: mprint("\'Timeo Mortis?\' asks Death quizzically, \'Not me!\'"); break; case 9: mprint("Death sighs theatrically. \'They never learn.\'"); break; } strengthen_death(m); } else { Level->site[m->x][m->y].creature = NULL; if(random_range(2) || (m->uniqueness != COMMON)) { corpse = (pob)malloc(sizeof(objtype)); make_corpse(corpse, m); drop_at(m->x, m->y, corpse); } plotspot(m->x, m->y, FALSE); switch(m->id) { case ML0 + 8: /* Hiscore NPC */ switch(m->aux2) { case 0: mprint("You hear a faroff dirge. You feel a sense of triumph."); break; case 1: case 2: case 3: case 4: case 5: case 6: mprint("You hear a faroff sound like angels crying..."); strcpy(Priest[1], nameprint()); Priestbehavior[1] = 2933; break; case 7: mprint("A furtive figure dashes out of the shadows, takes a look at"); mprint("the corpse, and runs away!"); strcpy(Shadowlord, nameprint()); Shadowlordbehavior = 2912; break; case 8: mprint("An aide-de-camp approaches, removes the corpse's insignia,"); mprint("and departs."); strcpy(Commandant, nameprint()); Commandantbehavior = 2912; break; case 9: mprint("An odd glow surrounds the corpse, and slowly fades."); strcpy(Archmage, nameprint()); Archmagebehavior = 2933; break; case 10: mprint("A demon materializes, takes a quick look at the corpse,"); mprint("and teleports away with a faint popping noise."); strcpy(Prime, nameprint()); Primebehavior = 2932; break; case 11: mprint("A sports columnist rushes forward and takes a quick photo"); mprint("of the corpse and rushes off muttering about a deadline."); strcpy(Champion, nameprint()); Championbehavior = 2913; break; case 12: mprint("You hear a fanfare in the distance, and feel dismayed."); strcpy(Duke, nameprint()); Dukebehavior = 2911; break; case 13: if(Player.alignment > 10) { mprint("You feel smug."); } else if(Player.alignment < 10) { mprint("You feel ashamed."); } strcpy(Chaoslord, nameprint()); Chaoslordbehavior = 2912; break; case 14: if(Player.alignment < 10) { mprint("You feel smug."); } else if(Player.alignment > 10) { mprint("You feel ashamed."); } strcpy(Lawlord, nameprint()); Lawlordbehavior = 2911; break; case 15: /* * Just a tad complicated. Promote a new justiciar if * an guards are left in the city, otherwise destroy * the Order! */ Player.alignment -= 100; if(!gamestatusp(DESTROYED_ORDER)) { mprint("In the distance you hear a trumpet. A Servent of Law"); mprint("materializes, sheds a tear, and leaves."); strcpy(Justiciar, nameprint()); Justiciarbehavior = 2911; /* Promote one of the city guards to be justiciar */ ml = City->mlist; while(!found && (ml != NULL)) { if((ml->m->id == (ML0 + 3)) && (ml->m->hp > 0)) { found = 1; } else { found = 0; } if(!found) { ml = ml->next; } } if(ml != NULL) { mprint("A new justiciar has been promoted!"); x = ml->m->x; y = ml->m->y; ml->m->x = x; ml->m->y = y; ml->m->click = (Tick + 1) % 60; m_status_reset(ml->m, AWAKE); m_status_reset(ml->m, HOSTILE); } /* * Will cause order to be destroyed if no guards or justiciar */ alert_guards(); } else { mprint("A Servant of Chaos materializes, grabs the corpse,"); mprint("snickers a bit, and vanishes."); } } break; case ML0 + 3: /* Guard */ Player.alignment -= 10; if((Current_Environment == E_CITY) || (Current_Environment == E_VILLAGE)) { alert_guards(); } break; case ML3 + 5: /* Goblin king */ if(!gamestatusp(ATTACKED_ORACLE)) { mprint("You seem to hear a woman's voice from far off:"); mprint("\'Well don! Come to me now...\'"); } setgamestatus(COMPLETED_CAVES); break; case ML7 + 5: /* Great worm */ if(!gamestatusp(ATTACKED_ORACLE)) { mprint("A female voice sounds from just behind your ear:"); mprint("\'Well fought! I have some new advice for you...\'"); } setgamestatus(COMPLETED_SEWERS); break; case ML10 + 1: setgamestatus(KILLED_EATER); break; case ML10 + 2: setgamestatus(KILLED_LAWBRINGER); break; case ML10 + 3: setgamestatus(KILLED_DRAGONLORD); break; case ML10 + 4: setgamestatus(COMPLETED_VOLCANO); if(!gamestatusp(ATTACKED_ORACLE)) { mprint("You feel a soft touch on your shoulder..."); mprint("You turn around but there is no one there!"); mprint("You turn back and see a not: \'See me soon.\'"); mprint("The note vanishes in a burst of blue fire!"); } break; case ML10 + 9: /* Elemental master */ if(!gamestatusp(ATTACKED_ORACLE)) { mprint("Words appear before you, traced in blue flame!"); mprint("\'Return to the Prime Plane via the Circle of Sorcerors..."); } break; } } dodrawspot(m->x, m->y); }