/* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */ /* mmelee */ /* various functions to do with monster melee */ #include "glob.h" void m_hit(pmt m, int dtype) { if (m->uniqueness == COMMON) { strcpy(Str3,"a "); strcat(Str3,m->monstring); } else strcpy(Str3,m->monstring); if ((Player.status[DISPLACED] > 0) && (random_range(2) == 1)) mprint("The attack was displaced!"); else p_damage(random_range(m->dmg),dtype,Str3); } /* execute monster attacks versus player */ void tacmonster(pmt m) { int i=0; drawvision(Player.x,Player.y); transcribe_monster_actions(m); while ((i < strlen(m->meleestr)) && (m->hp > 0)) { if (m->uniqueness == COMMON) { strcpy(Str4,"The "); strcat(Str4,m->monstring); } else strcpy(Str4,m->monstring); if (m->meleestr[i] == 'A') { strcat(Str4," attacks "); strcat(Str4,actionlocstr(m->meleestr[i+1])); if (Verbosity == VERBOSE) mprint(Str4); monster_melee(m,m->meleestr[i+1],0); } else if (m->meleestr[i] == 'L') { strcat(Str4," lunges "); strcat(Str4,actionlocstr(m->meleestr[i+1])); if (Verbosity == VERBOSE) mprint(Str4); monster_melee(m,m->meleestr[i+1],m->level); } i+=2; } } void monster_melee(pmt m, char hitloc, int bonus) { if (player_on_sanctuary()) print1("The aegis of your deity protects you!"); else { /* being attacked wakes you up/stops fast move */ resetgamestatus(FAST_MOVE); /* It's lawful to wait to be attacked */ if (m->attacked==0) Player.alignment++; m->attacked++; if (m->uniqueness == COMMON) { strcpy(Str2,"The "); strcat(Str2,m->monstring); } else strcpy(Str2,m->monstring); if (monster_hit(m,hitloc,bonus)) switch(m->meleef) { case M_NO_OP: strcat(Str2," touches you."); mprint(Str2); break; case M_MELEE_NORMAL: strcat(Str2," hits you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); break; case M_MELEE_NG: strcat(Str2," hits you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); if (random_range(5)==3) m_sp_ng(m); break; case M_MELEE_FIRE: strcat(Str2," blasts you with fire."); mprint(Str2); m_hit(m,FLAME); break; case M_MELEE_DRAGON: strcat(Str2," hits you and blasts you with fire."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); m_hit(m,FLAME); break; case M_MELEE_ELEC: strcat(Str2," lashes you with electricity."); mprint(Str2); m_hit(m,ELECTRICITY); break; case M_MELEE_COLD: strcat(Str2," freezes you with cold."); mprint(Str2); m_hit(m,ELECTRICITY); break; case M_MELEE_POISON: strcat(Str2," hits you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); if (random_range(10) < m->level) { mprint("You've been poisoned!"); p_poison(m->dmg); } break; case M_MELEE_GRAPPLE: strcat(Str2," grabs you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); Player.status[IMMOBILE]++; break; case M_MELEE_SPIRIT: strcat(Str2," touches you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); drain_life(m->level); break; case M_MELEE_DISEASE: strcat(Str2," hits you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); if (random_range(10) < m->level) { mprint("You've been infected!"); disease(m->level); } break; case M_MELEE_SLEEP: strcat(Str2," hit you."); mprint(Str2); m_hit(m,NORMAL_DAMAGE); if (random_range(10) < m->level) { mprint("You feel drowsy"); sleep_player(m->level); } break; } else { if (random_range(10)) strcat(Str2," missed you."); else { if (Verbosity == TERSE) { switch(random_range(10)) { case 0: strcat(Str2," blundered severely."); m_damage(m,m->dmg,UNSTOPPABLE); break; case 1: strcat(Str2," tripped while attacking.");m_dropstuff(m);break; case 2: strcat(Str2," seems seriously confused."); m->speed = min(30,m->speed*2); break; default: strcat(Str2," missed you."); } } switch(random_range(10)) { case 0: strcat(Str2," flailed stupidly at you."); break; case 1: strcat(Str2," made you laugh."); break; case 2: strcat(Str2," blundered severely."); m_damage(m,m->dmg,UNSTOPPABLE); break; case 3: strcat(Str2," tripped while attacking.");m_dropstuff(m);break; case 4: strcat(Str2," seems seriously confused."); m->speed = min(30,m->speed*2); break; case 5: strcat(Str2," is seriously ashamed."); break; case 6: strcat(Str2," made a boo-boo."); break; case 7: strcat(Str2," blundered."); break; case 8: strcat(Str2," cries out in anger and frustration."); break; case 9: strcat(Str2," curses your ancestry."); break; } } mprint(Str2); } } } /* checks to see if player hits with hitmod vs. monster m at location hitloc */ int monster_hit(pmt m, char hitloc, int bonus) { int i=0,blocks=FALSE,goodblocks=0,hit,riposte=FALSE; while (ihit+bonus,Player.defense+goodblocks*10); if ((! hit) && (goodblocks > 0)) { if (Verbosity == VERBOSE) mprint("You blocked it!"); if (riposte) { if (Verbosity != TERSE) mprint("You got a riposte!"); if (hitp(Player.hit,m->ac)) { mprint("You hit!"); weapon_use(0,Player.possessions[O_WEAPON_HAND],m); } else mprint("You missed."); } } return(hit); } /* decide monster actions in tactical combat mode */ /* if monster is skilled, it can try see the player's attacks coming and try to block appropriately. */ void transcribe_monster_actions(pmt m) { int i; char attack_loc,block_loc; static char mmstr[80]; int p_blocks[3]; int p_attacks[3]; for(i=0;i<3;i++)p_blocks[i] = p_attacks[i] = 0; /* Find which area player blocks and attacks least in */ i = 0; while (imeleestr = mmstr; if (m->id != NPC) strcpy(m->meleestr,Monsters[m->id].meleestr); else { strcpy(m->meleestr,""); for(i=0;ilevel;i+=2) strcat(m->meleestr,"L?R?"); } i = 0; while (imeleestr)) { if ((m->meleestr[i] == 'A') || (m->meleestr[i] == 'L')) { if (m->meleestr[i+1] == '?') { if (m->level+random_range(30) > Player.level+random_range(20)) m->meleestr[i+1] = attack_loc; else m->meleestr[i+1] = random_loc(); } else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc(); } else if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) { if (m->meleestr[i+1] == '?') { if (m->level+random_range(30) > Player.level+random_range(20)) m->meleestr[i+1] = block_loc; else m->meleestr[i+1] = random_loc(); } else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc(); } i+=2; } } char random_loc(void) { switch(random_range(3)) { case 0:return('H'); case 1:return('C'); default:return('L'); } }