LCOV - code coverage report
Current view: top level - omega-rpg-0.90-pa9 - mmelee.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 106 202 52.5 %
Date: 2017-09-08 22:00:26 Functions: 6 6 100.0 %
Branches: 77 161 47.8 %

           Branch data     Line data    Source code
       1                 :            : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
       2                 :            : /* mmelee */
       3                 :            : /* various functions to do with monster melee */
       4                 :            : 
       5                 :            : #include "glob.h"
       6                 :            : 
       7                 :            : 
       8                 :          3 : void m_hit(pmt m, int dtype)
       9                 :            : {
      10         [ +  - ]:          3 :   if (m->uniqueness == COMMON) {
      11                 :          3 :     strcpy(Str3,"a ");
      12                 :          3 :     strcat(Str3,m->monstring);
      13                 :            :   }
      14                 :          0 :   else strcpy(Str3,m->monstring);
      15 [ -  + ][ #  # ]:          3 :   if ((Player.status[DISPLACED] > 0) && (random_range(2) == 1))
      16                 :          0 :     mprint("The attack was displaced!");
      17                 :          3 :   else  p_damage(random_range(m->dmg),dtype,Str3);
      18                 :          3 : }
      19                 :            : 
      20                 :            : 
      21                 :            : 
      22                 :            : /* execute monster attacks versus player */
      23                 :         19 : void tacmonster(pmt m)
      24                 :            : {
      25                 :         19 :   int i=0;
      26                 :         19 :   drawvision(Player.x,Player.y);
      27                 :         19 :   transcribe_monster_actions(m);
      28 [ +  + ][ +  - ]:         95 :   while ((i < strlen(m->meleestr)) && (m->hp > 0)) {
      29         [ +  - ]:         76 :     if (m->uniqueness == COMMON) {
      30                 :         76 :       strcpy(Str4,"The ");
      31                 :         76 :       strcat(Str4,m->monstring);
      32                 :            :     }
      33                 :          0 :     else strcpy(Str4,m->monstring);
      34         [ +  + ]:         76 :     if (m->meleestr[i] == 'A') {
      35                 :         21 :       strcat(Str4," attacks ");
      36                 :         21 :       strcat(Str4,actionlocstr(m->meleestr[i+1]));
      37         [ +  - ]:         21 :       if (Verbosity == VERBOSE) mprint(Str4);
      38                 :         21 :       monster_melee(m,m->meleestr[i+1],0);
      39                 :            :     }
      40         [ -  + ]:         55 :     else if (m->meleestr[i] == 'L') {
      41                 :          0 :       strcat(Str4," lunges ");
      42                 :          0 :       strcat(Str4,actionlocstr(m->meleestr[i+1]));
      43         [ #  # ]:          0 :       if (Verbosity == VERBOSE) mprint(Str4);
      44                 :          0 :       monster_melee(m,m->meleestr[i+1],m->level);
      45                 :            :     }
      46                 :         76 :     i+=2;
      47                 :            :   }
      48                 :         19 : }
      49                 :            : 
      50                 :            : 
      51                 :            : 
      52                 :         21 : void monster_melee(pmt m, char hitloc, int bonus)
      53                 :            : {
      54         [ -  + ]:         21 :   if (player_on_sanctuary())
      55                 :          0 :     print1("The aegis of your deity protects you!");
      56                 :            :   else {
      57                 :            :     /* being attacked wakes you up/stops fast move */
      58                 :         21 :     resetgamestatus(FAST_MOVE);
      59                 :            : 
      60                 :            :     /* It's lawful to wait to be attacked */
      61         [ +  + ]:         21 :     if (m->attacked==0) Player.alignment++;
      62                 :         21 :     m->attacked++;
      63         [ +  - ]:         21 :     if (m->uniqueness == COMMON) {
      64                 :         21 :       strcpy(Str2,"The ");
      65                 :         21 :       strcat(Str2,m->monstring);
      66                 :            :     }
      67                 :          0 :     else strcpy(Str2,m->monstring);
      68         [ +  + ]:         21 :     if (monster_hit(m,hitloc,bonus))
      69   [ +  +  -  -  :          4 :       switch(m->meleef) {
          -  -  -  -  -  
             -  -  -  - ]
      70                 :            :       case M_NO_OP: 
      71                 :          1 :         strcat(Str2," touches you.");
      72                 :          1 :         mprint(Str2);
      73                 :          1 :         break;
      74                 :            :       case M_MELEE_NORMAL:
      75                 :          3 :         strcat(Str2," hits you.");
      76                 :          3 :         mprint(Str2);
      77                 :          3 :         m_hit(m,NORMAL_DAMAGE);
      78                 :          3 :         break;
      79                 :            :       case M_MELEE_NG:
      80                 :          0 :         strcat(Str2," hits you.");
      81                 :          0 :         mprint(Str2);
      82                 :          0 :         m_hit(m,NORMAL_DAMAGE);
      83         [ #  # ]:          0 :         if (random_range(5)==3) m_sp_ng(m);
      84                 :          0 :         break;
      85                 :            :       case M_MELEE_FIRE:
      86                 :          0 :         strcat(Str2," blasts you with fire.");
      87                 :          0 :         mprint(Str2);
      88                 :          0 :         m_hit(m,FLAME);
      89                 :          0 :         break;
      90                 :            :       case M_MELEE_DRAGON:
      91                 :          0 :         strcat(Str2," hits you and blasts you with fire.");
      92                 :          0 :         mprint(Str2);
      93                 :          0 :         m_hit(m,NORMAL_DAMAGE);
      94                 :          0 :         m_hit(m,FLAME);
      95                 :          0 :         break;
      96                 :            :       case M_MELEE_ELEC:
      97                 :          0 :         strcat(Str2," lashes you with electricity.");
      98                 :          0 :         mprint(Str2);
      99                 :          0 :         m_hit(m,ELECTRICITY);
     100                 :          0 :         break;
     101                 :            :       case M_MELEE_COLD:
     102                 :          0 :         strcat(Str2," freezes you with cold.");
     103                 :          0 :         mprint(Str2);
     104                 :          0 :         m_hit(m,ELECTRICITY);
     105                 :          0 :         break;
     106                 :            :       case M_MELEE_POISON:
     107                 :          0 :         strcat(Str2," hits you.");
     108                 :          0 :         mprint(Str2);
     109                 :          0 :         m_hit(m,NORMAL_DAMAGE);
     110         [ #  # ]:          0 :         if (random_range(10) < m->level) {
     111                 :          0 :           mprint("You've been poisoned!");
     112                 :          0 :           p_poison(m->dmg);
     113                 :            :         }
     114                 :          0 :         break;
     115                 :            :       case M_MELEE_GRAPPLE:
     116                 :          0 :         strcat(Str2," grabs you.");
     117                 :          0 :         mprint(Str2);
     118                 :          0 :         m_hit(m,NORMAL_DAMAGE);
     119                 :          0 :         Player.status[IMMOBILE]++;
     120                 :          0 :         break;
     121                 :            :       case M_MELEE_SPIRIT:
     122                 :          0 :         strcat(Str2," touches you.");
     123                 :          0 :         mprint(Str2);
     124                 :          0 :         m_hit(m,NORMAL_DAMAGE);
     125                 :          0 :         drain_life(m->level);
     126                 :          0 :         break;
     127                 :            :       case M_MELEE_DISEASE:
     128                 :          0 :         strcat(Str2," hits you.");
     129                 :          0 :         mprint(Str2);
     130                 :          0 :         m_hit(m,NORMAL_DAMAGE);
     131         [ #  # ]:          0 :         if (random_range(10) < m->level) {
     132                 :          0 :           mprint("You've been infected!");
     133                 :          0 :           disease(m->level);
     134                 :            :         }
     135                 :          0 :         break;
     136                 :            :       case M_MELEE_SLEEP:
     137                 :          0 :         strcat(Str2," hit you.");
     138                 :          0 :         mprint(Str2);
     139                 :          0 :         m_hit(m,NORMAL_DAMAGE);
     140         [ #  # ]:          0 :         if (random_range(10) < m->level) {
     141                 :          0 :           mprint("You feel drowsy");
     142                 :          0 :           sleep_player(m->level);
     143                 :            :         }
     144                 :          4 :         break;
     145                 :            :       }
     146                 :            :     else {
     147         [ +  + ]:         17 :       if (random_range(10)) strcat(Str2," missed you.");
     148                 :            :       else {
     149         [ -  + ]:          1 :         if (Verbosity == TERSE) {
     150   [ #  #  #  # ]:          0 :           switch(random_range(10)) {
     151                 :            :             case 0:
     152                 :          0 :               strcat(Str2," blundered severely.");
     153                 :          0 :               m_damage(m,m->dmg,UNSTOPPABLE); break;
     154                 :            :             case 1:
     155                 :          0 :               strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
     156                 :            :             case 2:
     157                 :          0 :               strcat(Str2," seems seriously confused.");
     158                 :          0 :               m->speed = min(30,m->speed*2); break;
     159                 :            :             default:
     160                 :          0 :               strcat(Str2," missed you.");
     161                 :            :           }
     162                 :            :         }
     163   [ -  -  -  -  :          1 :         switch(random_range(10)) {
          -  -  -  -  -  
                   +  - ]
     164                 :          0 :           case 0: strcat(Str2," flailed stupidly at you."); break;
     165                 :          0 :           case 1: strcat(Str2," made you laugh."); break;
     166                 :          0 :           case 2: strcat(Str2," blundered severely.");
     167                 :          0 :             m_damage(m,m->dmg,UNSTOPPABLE); break;
     168                 :          0 :           case 3: strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
     169                 :          0 :           case 4: strcat(Str2," seems seriously confused.");
     170                 :          0 :             m->speed = min(30,m->speed*2); break;
     171                 :          0 :           case 5: strcat(Str2," is seriously ashamed."); break;
     172                 :          0 :           case 6: strcat(Str2," made a boo-boo."); break;
     173                 :          0 :           case 7: strcat(Str2," blundered."); break;
     174                 :          0 :           case 8: strcat(Str2," cries out in anger and frustration."); break;
     175                 :          1 :           case 9: strcat(Str2," curses your ancestry."); break;
     176                 :            :         }
     177                 :            :       }
     178                 :         17 :       mprint(Str2);
     179                 :            :     }
     180                 :            :   }
     181                 :         21 : }
     182                 :            : 
     183                 :            : 
     184                 :            : 
     185                 :            : /* checks to see if player hits with hitmod vs. monster m at location hitloc */
     186                 :         21 : int monster_hit(pmt m, char hitloc, int bonus)
     187                 :            : {
     188                 :         21 :   int i=0,blocks=FALSE,goodblocks=0,hit,riposte=FALSE;
     189         [ +  + ]:         63 :   while (i<strlen(Player.meleestr)) {
     190 [ +  + ][ -  + ]:         42 :     if ((Player.meleestr[i] == 'B') || (Player.meleestr[i] == 'R')) {
     191                 :         21 :       blocks = TRUE;
     192         [ +  + ]:         21 :       if (hitloc == Player.meleestr[i+1]) {
     193                 :          4 :         goodblocks++;
     194         [ -  + ]:          4 :         if (Player.meleestr[i] == 'R') riposte = TRUE;
     195                 :            :       }
     196                 :            :     }
     197                 :         42 :     i+=2;
     198                 :            :   }
     199         [ -  + ]:         21 :   if (! blocks) goodblocks = -1;
     200                 :         21 :   hit = hitp(m->hit+bonus,Player.defense+goodblocks*10);
     201 [ +  + ][ +  + ]:         21 :   if ((! hit) && (goodblocks > 0)) {
     202         [ +  - ]:          4 :     if (Verbosity == VERBOSE) mprint("You blocked it!");
     203         [ -  + ]:          4 :     if (riposte) {
     204         [ #  # ]:          0 :       if (Verbosity != TERSE) mprint("You got a riposte!");
     205         [ #  # ]:          0 :       if (hitp(Player.hit,m->ac)) {
     206                 :          0 :         mprint("You hit!");
     207                 :          0 :         weapon_use(0,Player.possessions[O_WEAPON_HAND],m);
     208                 :            :       }
     209                 :          0 :       else mprint("You missed.");
     210                 :            :     }
     211                 :            :   }
     212                 :         21 :   return(hit);
     213                 :            : }
     214                 :            : 
     215                 :            : 
     216                 :            : 
     217                 :            : /* decide monster actions in tactical combat mode */
     218                 :            : /* if monster is skilled, it can try see the player's attacks coming and
     219                 :            :    try to block appropriately. */
     220                 :            : 
     221                 :         35 : void transcribe_monster_actions(pmt m)
     222                 :            : {
     223                 :            :   int i;
     224                 :            :   char attack_loc,block_loc;
     225                 :            :   static char mmstr[80];
     226                 :            :   
     227                 :            :   int p_blocks[3];
     228                 :            :   int p_attacks[3];
     229                 :            : 
     230         [ +  + ]:        140 :   for(i=0;i<3;i++)p_blocks[i] = p_attacks[i] = 0;
     231                 :            : 
     232                 :            :   /* Find which area player blocks and attacks least in */
     233                 :         35 :   i = 0;
     234         [ +  + ]:        105 :   while (i<strlen(Player.meleestr)) {
     235 [ +  + ][ -  + ]:         70 :     if ((Player.meleestr[i] == 'B') ||
     236                 :         35 :         (Player.meleestr[i] == 'R')) {
     237         [ +  + ]:         35 :       if (Player.meleestr[i+1] == 'H') p_blocks[0]++;
     238         [ +  + ]:         35 :       if (Player.meleestr[i+1] == 'C') p_blocks[1]++;
     239         [ +  + ]:         35 :       if (Player.meleestr[i+1] == 'L') p_blocks[2]++;
     240                 :            :     }
     241 [ +  - ][ -  + ]:         35 :     else if ((Player.meleestr[i] == 'A') ||
     242                 :         35 :              (Player.meleestr[i] == 'L')) {
     243         [ #  # ]:          0 :       if (Player.meleestr[i+1] == 'H') p_attacks[0]++;
     244         [ #  # ]:          0 :       if (Player.meleestr[i+1] == 'C') p_attacks[1]++;
     245         [ #  # ]:          0 :       if (Player.meleestr[i+1] == 'L') p_attacks[2]++;
     246                 :            :     }
     247                 :         70 :     i+=2;
     248                 :            :   }
     249                 :            : 
     250 [ +  + ][ +  - ]:         35 :   if ((p_blocks[2] <= p_blocks[1]) &&
     251                 :         14 :       (p_blocks[2] <= p_blocks[0]))
     252                 :         14 :     attack_loc = 'L';
     253 [ +  - ][ +  - ]:         21 :   else if ((p_blocks[1] <= p_blocks[2]) &&
     254                 :         21 :            (p_blocks[1] <= p_blocks[0]))
     255                 :         21 :     attack_loc = 'C'; /* DG 12/31/98 */
     256                 :          0 :   else attack_loc = 'H';
     257 [ +  - ][ +  - ]:         35 :   if ((p_attacks[2] <= p_attacks[1]) &&
     258                 :         35 :       (p_attacks[2] <= p_attacks[0]))
     259                 :         35 :     block_loc = 'L';
     260 [ #  # ][ #  # ]:          0 :   else if ((p_attacks[1] <= p_attacks[2]) &&
     261                 :          0 :            (p_attacks[1] <= p_attacks[0]))
     262                 :          0 :     block_loc = 'C';
     263                 :          0 :   else block_loc = 'H';
     264                 :            : 
     265                 :         35 :   m->meleestr = mmstr;
     266                 :            : 
     267         [ +  - ]:         35 :   if (m->id != NPC)
     268                 :         35 :     strcpy(m->meleestr,Monsters[m->id].meleestr);
     269                 :            :   else {
     270                 :          0 :     strcpy(m->meleestr,"");
     271         [ #  # ]:          0 :     for(i=0;i<m->level;i+=2) 
     272                 :          0 :       strcat(m->meleestr,"L?R?");
     273                 :            :   }
     274                 :            : 
     275                 :         35 :   i = 0;
     276         [ +  + ]:        175 :   while (i<strlen(m->meleestr)) {
     277 [ +  + ][ -  + ]:        140 :     if ((m->meleestr[i] == 'A') || (m->meleestr[i] == 'L')) {
     278         [ +  + ]:         76 :       if (m->meleestr[i+1] == '?') {
     279         [ +  + ]:         33 :         if (m->level+random_range(30) > Player.level+random_range(20))
     280                 :         23 :           m->meleestr[i+1] = attack_loc;
     281                 :         33 :         else m->meleestr[i+1] = random_loc();
     282                 :            :       }
     283         [ +  - ]:          5 :       else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
     284                 :            :     }
     285 [ -  + ][ #  # ]:        102 :     else if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) {
     286         [ +  - ]:        102 :       if (m->meleestr[i+1] == '?') { 
     287         [ +  + ]:        102 :         if (m->level+random_range(30) > Player.level+random_range(20))
     288                 :         79 :           m->meleestr[i+1] = block_loc;
     289                 :        102 :         else m->meleestr[i+1] = random_loc();
     290                 :            :       }
     291         [ #  # ]:          0 :       else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
     292                 :            :     }
     293                 :        140 :     i+=2;
     294                 :            :   }
     295                 :         35 : }
     296                 :            : 
     297                 :         38 : char random_loc(void)
     298                 :            : {
     299      [ +  +  + ]:         38 :   switch(random_range(3)) {
     300                 :         12 :   case 0:return('H');
     301                 :         16 :   case 1:return('C');
     302                 :         10 :   default:return('L');
     303                 :            :   }
     304                 :            : }

Generated by: LCOV version 1.11