src/hcode/btech/mech.hitloc.c

Go to the documentation of this file.
00001 /*
00002  * Author: Markus Stenberg <fingon@iki.fi>
00003  *
00004  *  Copyright (c) 1996 Markus Stenberg
00005  *  Copyright (c) 1998-2002 Thomas Wouters
00006  *  Copyright (c) 2000-2002 Cord Awtry
00007  *       All rights reserved
00008  */
00009 
00010 #include "mech.h"
00011 #include "mech.events.h"
00012 #include "p.mech.utils.h"
00013 #include "p.mech.combat.h"
00014 #include "p.mech.damage.h"
00015 #include "p.aero.bomb.h"
00016 #include "p.mech.update.h"
00017 #include "p.crit.h"
00018 
00019 #define CHECK_ZERO_LOC(mech,a,b) ( GetSectInt(mech, a) > 0 ? a : b )
00020 
00021 int FindPunchLocation(MECH *target, int hitGroup) {
00022 
00023     int roll = Number(1, 6);
00024 
00025     /* New tables from Total Warfare - pg 147 (and back of book)
00026      * - Dany 01/2007 */
00027     if (MechIsQuad(target)) {
00028 
00029         switch (hitGroup) {
00030             case LEFTSIDE:
00031                 switch (roll) {
00032                     case 1:
00033                     case 2:
00034                         return LTORSO; 
00035                     case 3:
00036                         return CTORSO;
00037                     case 4:
00038                         /* Front Left Leg */
00039                         return LARM; 
00040                     case 5:
00041                         /* Rear Left Leg */
00042                         return LLEG;
00043                     case 6:
00044                         return HEAD;
00045                 }
00046                 break;
00047 
00048             case RIGHTSIDE:
00049                 switch (roll) {
00050                     case 1:
00051                     case 2:
00052                         return RTORSO;
00053                     case 3:
00054                         return CTORSO;
00055                     case 4:
00056                         /* Front Right Leg */
00057                         return RARM;
00058                     case 5:
00059                         /* Rear Right Leg */
00060                         return RLEG;
00061                     case 6:
00062                         return HEAD;
00063                 }
00064                 break;
00065 
00066             case BACK:
00067             case FRONT:
00068                 switch (roll) {
00069                     case 1:
00070                         if (hitGroup == BACK) {
00071                             /* Rear Left Leg */
00072                             return LLEG;
00073                         } else {
00074                             /* Front Left Leg */
00075                             return LARM;
00076                         }
00077                     case 2:
00078                         return LTORSO;
00079                     case 3:
00080                         return CTORSO;
00081                     case 4:
00082                         return RTORSO;
00083                     case 5:
00084                         if (hitGroup == BACK) {
00085                             /* Rear Right Leg */
00086                             return RLEG;
00087                         } else {
00088                             /* Front Right Leg */
00089                             return RARM;
00090                         }
00091                     case 6:
00092                         return HEAD;
00093                 }
00094                 break;
00095         }
00096 
00097     } else {
00098 
00099         /* Biped Mech */
00100         switch (hitGroup) {
00101             case LEFTSIDE:
00102                 switch (roll) {
00103                     case 1:
00104                     case 2:
00105                         return LTORSO;
00106                     case 3:
00107                         return CTORSO;
00108                     case 4:
00109                     case 5:
00110                         return LARM;
00111                     case 6:
00112                         return HEAD;
00113                 }
00114                 break;
00115 
00116             case BACK:
00117             case FRONT:
00118                 switch (roll) {
00119                     case 1:
00120                         return LARM;
00121                     case 2:
00122                         return LTORSO;
00123                     case 3:
00124                         return CTORSO;
00125                     case 4:
00126                         return RTORSO;
00127                     case 5:
00128                         return RARM;
00129                     case 6:
00130                         return HEAD;
00131                 }
00132                 break;
00133 
00134             case RIGHTSIDE:
00135                 switch (roll) {
00136                     case 1:
00137                     case 2:
00138                         return RTORSO;
00139                     case 3:
00140                         return CTORSO;
00141                     case 4:
00142                     case 5:
00143                         return RARM;
00144                     case 6:
00145                         return HEAD;
00146                 }
00147                 break;
00148         }
00149     }
00150 
00151     /* Should never reach this point unless
00152      * someone uses this function wrong */
00153     return -1;
00154 }
00155 
00156 int FindKickLocation(MECH *target, int hitGroup) {
00157 
00158     int roll = Number(1, 6);
00159 
00160     /* New tables from Total Warfare for quads */
00161     if (MechIsQuad(target)) {
00162 
00163         switch (hitGroup) {
00164             case LEFTSIDE:
00165                 switch (roll) {
00166                     case 1:
00167                     case 2:
00168                     case 3:
00169                         /* Left Front Leg */
00170                         return LARM;
00171                     case 4:
00172                     case 5:
00173                     case 6:
00174                         /* Left Rear Leg */
00175                         return LLEG;
00176                 }
00177                 break;
00178 
00179             case RIGHTSIDE:
00180                 switch (roll) {
00181                     case 1:
00182                     case 2:
00183                     case 3:
00184                         /* Right Front Leg */
00185                         return RARM;
00186                     case 4:
00187                     case 5:
00188                     case 6:
00189                         /* Right Rear Leg */
00190                         return RLEG;
00191                 }
00192                 break;
00193 
00194             case BACK:
00195             case FRONT:
00196                 switch (roll) {
00197                     case 1:
00198                     case 2:
00199                     case 3:
00200                         if (hitGroup == BACK) {
00201                             /* Right Rear Leg */
00202                             return RLEG;
00203                         } else {
00204                             /* Right Front Leg */
00205                             return RARM;
00206                         }
00207                     case 4:
00208                     case 5:
00209                     case 6:
00210                         if (hitGroup == BACK) {
00211                             /* Left Rear Leg */
00212                             return LLEG;
00213                         } else {
00214                             /* Left Front Leg */
00215                             return LARM;
00216                         }
00217                 }
00218         }
00219 
00220     } else {
00221 
00222         switch (hitGroup) {
00223             case LEFTSIDE:
00224                 return LLEG;
00225             case BACK:
00226             case FRONT:
00227                 switch (roll) {
00228                     case 1:
00229                     case 2:
00230                     case 3:
00231                         return RLEG;
00232                     case 4:
00233                     case 5:
00234                     case 6:
00235                         return LLEG;
00236                 }
00237             case RIGHTSIDE:
00238                 return RLEG;
00239         }
00240     }
00241 
00242     /* Should never get to this point but will include this
00243      * as a safeguard.  Should probably have the value
00244      * returned from this function checked anyways. */
00245     return -1;
00246 }
00247 
00248 /*
00249  * Exile stun code - Used when a mech takes a hit to the head
00250  * instead of doing damage to the head it stuns the pilot
00251  * and re-rolls the location
00252  */
00253 int ModifyHeadHit(int hitGroup, MECH *mech) {
00254 
00255     int newloc = FindPunchLocation(mech, hitGroup);
00256 
00257     if (MechType(mech) != CLASS_MECH) {
00258         return newloc;
00259     }
00260 
00261     if (newloc != HEAD) {
00262 
00263         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00264         mech_notify(mech, MECHALL,
00265                 "The cockpit violently shakes from a grazing blow! "
00266                 "You are momentarily stunned!");
00267 
00268         if (CrewStunning(mech)) {
00269             StopCrewStunning(mech);
00270         }
00271 
00272         MechLOSBroadcast(mech,
00273                 "significantly slows down and starts wobbling!");
00274 
00275         MechCritStatus(mech) |= MECH_STUNNED;
00276 
00277         if (MechSpeed(mech) > WalkingSpeed(MechMaxSpeed(mech))) {
00278             MechDesiredSpeed(mech) = WalkingSpeed(MechMaxSpeed(mech));
00279         }
00280 
00281         MECHEVENT(mech, EVENT_CREWSTUN, mech_crewstun_event, MECHSTUN_TICK, 0);
00282     }
00283     return newloc;
00284 }
00285 
00286 int get_bsuit_hitloc(MECH * mech)
00287 {
00288         int i;
00289         int table[NUM_BSUIT_MEMBERS];
00290         int last = 0;
00291 
00292         for(i = 0; i < NUM_BSUIT_MEMBERS; i++)
00293                 if(GetSectInt(mech, i))
00294                         table[last++] = i;
00295         if(!last)
00296                 return -1;
00297         return table[Number(0, last - 1)];
00298 }
00299 
00300 int TransferTarget(MECH * mech, int hitloc)
00301 {
00302         switch (MechType(mech)) {
00303         case CLASS_BSUIT:
00304                 return get_bsuit_hitloc(mech);
00305         case CLASS_AERO:
00306         case CLASS_MECH:
00307         case CLASS_MW:
00308                 switch (hitloc) {
00309                 case RARM:
00310                 case RLEG:
00311                         return RTORSO;
00312                         break;
00313                 case LARM:
00314                 case LLEG:
00315                         return LTORSO;
00316                         break;
00317                 case RTORSO:
00318                 case LTORSO:
00319                         return CTORSO;
00320                         break;
00321                 }
00322                 break;
00323         }
00324         return -1;
00325 }
00326 
00327 int FindSwarmHitLocation(int *iscritical, int *isrear)
00328 {
00329         *isrear = 0;
00330         *iscritical = 1;
00331 
00332         switch (Roll()) {
00333         case 12:
00334         case 2:
00335                 return HEAD;
00336         case 3:
00337         case 11:
00338                 *isrear = 1;
00339                 return CTORSO;
00340         case 4:
00341                 *isrear = 1;
00342         case 5:
00343                 return RTORSO;
00344         case 10:
00345                 *isrear = 1;
00346         case 9:
00347                 return LTORSO;
00348         case 6:
00349                 return RARM;
00350         case 8:
00351                 return LARM;
00352         case 7:
00353                 return CTORSO;
00354         }
00355         return HEAD;
00356 }
00357 
00358 /*
00359  * Determines whether a section is crittable.
00360  * tres = armor percentage threshhold
00361  */
00362 int crittable(MECH * mech, int loc, int tres)
00363 {
00364         int d;
00365 
00366         if(MechSpecials(mech) & CRITPROOF_TECH)
00367                 return 0;
00368         /* Towers and Stationary Objectives should not crit */
00369         if(MechMove(mech) == MOVE_NONE)
00370                 return 0;
00371         if(!GetSectOArmor(mech, loc))
00372                 return 1;
00373         if(MechType(mech) != CLASS_MECH && mudconf.btech_vcrit <= 1)
00374                 return 0;
00375 
00376         /* Calculate percentage of armor remaining */
00377         d = (100 * GetSectArmor(mech, loc)) / GetSectOArmor(mech, loc);
00378 
00379         /* Are we below the threshold? */
00380         if(d < tres)
00381                 return 1;
00382         if(d == 100) {
00383                 if(Number(1, 71) == 23)
00384                         return 1;
00385                 return 0;
00386         }
00387         if(d < (100 - ((100 - tres) / 2)))
00388                 if(Number(1, 11) == 6)
00389                         return 1;
00390         return 0;
00391 }                                                               /* end crittable() */
00392 
00393 int FindFasaHitLocation(MECH * mech, int hitGroup, int *iscritical,
00394                                                 int *isrear)
00395 {
00396         int roll, hitloc = 0;
00397         int side;
00398 
00399         *iscritical = 0;
00400         roll = Roll();
00401 
00402         if(MechStatus(mech) & COMBAT_SAFE)
00403                 return 0;
00404 
00405         if(MechDugIn(mech) && GetSectOInt(mech, TURRET) && Number(1, 100) >= 42)
00406                 return TURRET;
00407 
00408         rollstat.hitrolls[roll - 2]++;
00409         rollstat.tothrolls++;
00410         switch (MechType(mech)) {
00411         case CLASS_BSUIT:
00412                 if((hitloc = get_bsuit_hitloc(mech)) < 0)
00413                         return Number(0, NUM_BSUIT_MEMBERS - 1);
00414         case CLASS_MW:
00415         case CLASS_MECH:
00416                 switch (hitGroup) {
00417                 case LEFTSIDE:
00418                         switch (roll) {
00419                         case 2:
00420                                 *iscritical = 1;
00421                                 return LTORSO;
00422                         case 3:
00423                                 return LLEG;
00424                         case 4:
00425                         case 5:
00426                                 return LARM;
00427                         case 6:
00428                                 return LLEG;
00429                         case 7:
00430                                 return LTORSO;
00431                         case 8:
00432                                 return CTORSO;
00433                         case 9:
00434                                 return RTORSO;
00435                         case 10:
00436                                 return RARM;
00437                         case 11:
00438                                 return RLEG;
00439                         case 12:
00440                                 if(mudconf.btech_exile_stun_code)
00441                                         return ModifyHeadHit(hitGroup, mech);
00442                                 return HEAD;
00443                         }
00444                 case RIGHTSIDE:
00445                         switch (roll) {
00446                         case 2:
00447                                 *iscritical = 1;
00448                                 return RTORSO;
00449                         case 3:
00450                                 return RLEG;
00451                         case 4:
00452                         case 5:
00453                                 return RARM;
00454                         case 6:
00455                                 return RLEG;
00456                         case 7:
00457                                 return RTORSO;
00458                         case 8:
00459                                 return CTORSO;
00460                         case 9:
00461                                 return LTORSO;
00462                         case 10:
00463                                 return LARM;
00464                         case 11:
00465                                 return LLEG;
00466                         case 12:
00467                                 if(mudconf.btech_exile_stun_code)
00468                                         return ModifyHeadHit(hitGroup, mech);
00469                                 return HEAD;
00470                         }
00471                 case FRONT:
00472                 case BACK:
00473                         switch (roll) {
00474                         case 2:
00475                                 *iscritical = 1;
00476                                 return CTORSO;
00477                         case 3:
00478                         case 4:
00479                                 return RARM;
00480                         case 5:
00481                                 return RLEG;
00482                         case 6:
00483                                 return RTORSO;
00484                         case 7:
00485                                 return CTORSO;
00486                         case 8:
00487                                 return LTORSO;
00488                         case 9:
00489                                 return LLEG;
00490                         case 10:
00491                         case 11:
00492                                 return LARM;
00493                         case 12:
00494                                 if(mudconf.btech_exile_stun_code)
00495                                         return ModifyHeadHit(hitGroup, mech);
00496                                 return HEAD;
00497                         }
00498                 }
00499                 break;
00500         case CLASS_VEH_GROUND:
00501                 switch (hitGroup) {
00502 
00503                 case LEFTSIDE:
00504                         switch (roll) {
00505                         case 2:
00506                                 /* A Roll on Determining Critical Hits Table */
00507                                 *iscritical = 1;
00508                                 return LSIDE;
00509                         case 3:
00510                                 if(mudconf.btech_tankfriendly) {
00511                                         if(!Fallen(mech)) {
00512                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00513                                                 switch (MechMove(mech)) {
00514                                                 case MOVE_TRACK:
00515                                                         mech_notify(mech, MECHALL,
00516                                                                                 "One of your tracks is seriously damaged!");
00517                                                         break;
00518                                                 case MOVE_WHEEL:
00519                                                         mech_notify(mech, MECHALL,
00520                                                                                 "One of your wheels is seriously damaged!");
00521                                                         break;
00522                                                 case MOVE_HOVER:
00523                                                         mech_notify(mech, MECHALL,
00524                                                                                 "Your air skirt is seriously damaged!");
00525                                                         break;
00526                                                 case MOVE_HULL:
00527                                                 case MOVE_SUB:
00528                                                 case MOVE_FOIL:
00529                                                         mech_notify(mech, MECHALL,
00530                                                                                 "Your craft lurches and suddenly loses a lot of speed!");
00531                                                         break;
00532                                                 }
00533                                                 LowerMaxSpeed(mech, MP2);
00534                                         }
00535                                         return LSIDE;
00536                                 }
00537                                 /* Cripple tank */
00538                                 if(!Fallen(mech)) {
00539                                         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00540                                         switch (MechMove(mech)) {
00541                                         case MOVE_TRACK:
00542                                                 mech_notify(mech, MECHALL,
00543                                                                         "One of your tracks is destroyed, immobilizing your vehicle!");
00544                                                 break;
00545                                         case MOVE_WHEEL:
00546                                                 mech_notify(mech, MECHALL,
00547                                                                         "One of your wheels is destroyed, immobilizing your vehicle!");
00548                                                 break;
00549                                         case MOVE_HOVER:
00550                                                 mech_notify(mech, MECHALL,
00551                                                                         "Your lift fan is destroyed, immobilizing your vehicle!");
00552                                                 break;
00553                                         case MOVE_HULL:
00554                                         case MOVE_SUB:
00555                                         case MOVE_FOIL:
00556                                                 mech_notify(mech, MECHALL,
00557                                                                         "Your engines cut out and you drift to a halt!");
00558                                         }
00559                                         SetMaxSpeed(mech, 0.0);
00560 
00561                                         MakeMechFall(mech);
00562                                 }
00563                                 return LSIDE;
00564                         case 4:
00565                         case 5:
00566                                 /* MP -1 */
00567                                 if(!Fallen(mech)) {
00568                                         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00569                                         switch (MechMove(mech)) {
00570                                         case MOVE_TRACK:
00571                                                 mech_notify(mech, MECHALL,
00572                                                                         "One of your tracks is damaged!");
00573                                                 break;
00574                                         case MOVE_WHEEL:
00575                                                 mech_notify(mech, MECHALL,
00576                                                                         "One of your wheels is damaged!");
00577                                                 break;
00578                                         case MOVE_HOVER:
00579                                                 mech_notify(mech, MECHALL,
00580                                                                         "Your air skirt is damaged!");
00581                                                 break;
00582                                         case MOVE_HULL:
00583                                         case MOVE_SUB:
00584                                         case MOVE_FOIL:
00585                                                 mech_notify(mech, MECHALL, "Your craft suddenly slows!");
00586                                                 break;
00587                                         }
00588                                         LowerMaxSpeed(mech, MP1);
00589                                 }
00590                                 return LSIDE;
00591                                 break;
00592                         case 6:
00593                         case 7:
00594                         case 8:
00595                         case 9:
00596                                 /* MP -1 if hover */
00597                                 return LSIDE;
00598                         case 10:
00599                                 return (GetSectInt(mech, TURRET)) ? TURRET : LSIDE;
00600                         case 11:
00601                                 if(GetSectInt(mech, TURRET)) {
00602                                         if(!(MechTankCritStatus(mech) & TURRET_LOCKED)) {
00603                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00604                                                 MechTankCritStatus(mech) |= TURRET_LOCKED;
00605                                                 mech_notify(mech, MECHALL,
00606                                                                         "Your turret takes a direct hit and locks up!");
00607                                         }
00608                                         return TURRET;
00609                                 } else
00610                                         return LSIDE;
00611                         case 12:
00612                                 /* A Roll on Determining Critical Hits Table */
00613                                 *iscritical = 1;
00614                                 return LSIDE;
00615                         }
00616                         break;
00617                 case RIGHTSIDE:
00618                         switch (roll) {
00619                         case 2:
00620                                 *iscritical = 1;
00621                                 return RSIDE;
00622                         case 3:
00623                                 if(mudconf.btech_tankfriendly) {
00624                                         if(!Fallen(mech)) {
00625                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00626                                                 switch (MechMove(mech)) {
00627                                                 case MOVE_TRACK:
00628                                                         mech_notify(mech, MECHALL,
00629                                                                                 "One of your tracks is seriously damaged!");
00630                                                         break;
00631                                                 case MOVE_WHEEL:
00632                                                         mech_notify(mech, MECHALL,
00633                                                                                 "One of your wheels is seriously damaged!");
00634                                                         break;
00635                                                 case MOVE_HOVER:
00636                                                         mech_notify(mech, MECHALL,
00637                                                                                 "Your air skirt is seriously damaged!");
00638                                                         break;
00639                                                 case MOVE_HULL:
00640                                                 case MOVE_SUB:
00641                                                 case MOVE_FOIL:
00642                                                         mech_notify(mech, MECHALL,
00643                                                                                 "Your craft lurches and suddenly loses a lot of speed!");
00644                                                         break;
00645                                                 }
00646                                                 LowerMaxSpeed(mech, MP2);
00647                                         }
00648                                         return RSIDE;
00649                                 }
00650                                 /* Cripple Tank */
00651                                 if(!Fallen(mech)) {
00652                                         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00653                                         switch (MechMove(mech)) {
00654                                         case MOVE_TRACK:
00655                                                 mech_notify(mech, MECHALL,
00656                                                                         "One of your tracks is destroyed, immobilizing your vehicle!");
00657                                                 break;
00658                                         case MOVE_WHEEL:
00659                                                 mech_notify(mech, MECHALL,
00660                                                                         "One of your wheels is destroyed, immobilizing your vehicle!");
00661                                                 break;
00662                                         case MOVE_HOVER:
00663                                                 mech_notify(mech, MECHALL,
00664                                                                         "Your lift fan is destroyed, immobilizing your vehicle!");
00665                                                 break;
00666                                         case MOVE_HULL:
00667                                         case MOVE_SUB:
00668                                         case MOVE_FOIL:
00669                                                 mech_notify(mech, MECHALL,
00670                                                                         "Your engines cut out and you drift to a halt!");
00671                                         }
00672                                         SetMaxSpeed(mech, 0.0);
00673 
00674                                         MakeMechFall(mech);
00675                                 }
00676                                 return RSIDE;
00677                         case 4:
00678                         case 5:
00679                                 /* MP -1 */
00680                                 if(!Fallen(mech)) {
00681                                         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00682                                         switch (MechMove(mech)) {
00683                                         case MOVE_TRACK:
00684                                                 mech_notify(mech, MECHALL,
00685                                                                         "One of your tracks is damaged!");
00686                                                 break;
00687                                         case MOVE_WHEEL:
00688                                                 mech_notify(mech, MECHALL,
00689                                                                         "One of your wheels is damaged!");
00690                                                 break;
00691                                         case MOVE_HOVER:
00692                                                 mech_notify(mech, MECHALL,
00693                                                                         "Your air skirt is damaged!");
00694                                                 break;
00695                                         case MOVE_HULL:
00696                                         case MOVE_SUB:
00697                                         case MOVE_FOIL:
00698                                                 mech_notify(mech, MECHALL, "Your craft suddenly slows!");
00699                                                 break;
00700                                         }
00701                                         LowerMaxSpeed(mech, MP1);
00702                                 }
00703                                 return RSIDE;
00704                         case 6:
00705                         case 7:
00706                         case 8:
00707                                 return RSIDE;
00708                         case 9:
00709                                 /* MP -1 if hover */
00710                                 if(!Fallen(mech)) {
00711                                         if(MechMove(mech) == MOVE_HOVER) {
00712                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00713                                                 mech_notify(mech, MECHALL,
00714                                                                         "Your air skirt is damaged!");
00715                                                 LowerMaxSpeed(mech, MP1);
00716                                         }
00717                                 }
00718                                 return RSIDE;
00719                         case 10:
00720                                 return (GetSectInt(mech, TURRET)) ? TURRET : RSIDE;
00721                         case 11:
00722                                 if(GetSectInt(mech, TURRET)) {
00723                                         if(!(MechTankCritStatus(mech) & TURRET_LOCKED)) {
00724                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00725                                                 MechTankCritStatus(mech) |= TURRET_LOCKED;
00726                                                 mech_notify(mech, MECHALL,
00727                                                                         "Your turret takes a direct hit and locks up!");
00728                                         }
00729                                         return TURRET;
00730                                 } else
00731                                         return RSIDE;
00732                         case 12:
00733                                 /* A Roll on Determining Critical Hits Table */
00734                                 *iscritical = 1;
00735                                 return RSIDE;
00736                         }
00737                         break;
00738 
00739                 case FRONT:
00740                 case BACK:
00741                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
00742                         switch (roll) {
00743                         case 2:
00744                                 /* A Roll on Determining Critical Hits Table */
00745                                 *iscritical = 1;
00746                                 return side;
00747                         case 3:
00748                                 if(mudconf.btech_tankshield) {
00749                                         if(mudconf.btech_tankfriendly) {
00750                                                 if(!Fallen(mech)) {
00751                                                         mech_notify(mech, MECHALL,
00752                                                                                 "%ch%cyCRITICAL HIT!%c");
00753                                                         switch (MechMove(mech)) {
00754                                                         case MOVE_TRACK:
00755                                                                 mech_notify(mech, MECHALL,
00756                                                                                         "One of your tracks is seriously damaged!");
00757                                                                 break;
00758                                                         case MOVE_WHEEL:
00759                                                                 mech_notify(mech, MECHALL,
00760                                                                                         "One of your wheels is seriously damaged!");
00761                                                                 break;
00762                                                         case MOVE_HOVER:
00763                                                                 mech_notify(mech, MECHALL,
00764                                                                                         "Your air skirt is seriously damaged!");
00765                                                                 break;
00766                                                         case MOVE_HULL:
00767                                                         case MOVE_SUB:
00768                                                         case MOVE_FOIL:
00769                                                                 mech_notify(mech, MECHALL,
00770                                                                                         "Your craft lurches and suddenly loses a lot of speed!");
00771                                                                 break;
00772                                                         }
00773                                                         LowerMaxSpeed(mech, MP2);
00774                                                 }
00775                                                 return side;
00776                                         }
00777                                         /* Cripple tank */
00778                                         if(!Fallen(mech)) {
00779                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00780                                                 switch (MechMove(mech)) {
00781                                                 case MOVE_TRACK:
00782                                                         mech_notify(mech, MECHALL,
00783                                                                                 "One of your tracks is destroyed, immobilizing your vehicle!");
00784                                                         break;
00785                                                 case MOVE_WHEEL:
00786                                                         mech_notify(mech, MECHALL,
00787                                                                                 "One of your wheels is destroyed, immobilizing your vehicle!");
00788                                                         break;
00789                                                 case MOVE_HOVER:
00790                                                         mech_notify(mech, MECHALL,
00791                                                                                 "Your lift fan is destroyed, immobilizing your vehicle!");
00792                                                         break;
00793                                                 case MOVE_HULL:
00794                                                 case MOVE_SUB:
00795                                                 case MOVE_FOIL:
00796                                                         mech_notify(mech, MECHALL,
00797                                                                                 "Your engines cut out and you drift to a halt!");
00798                                                 }
00799                                                 SetMaxSpeed(mech, 0.0);
00800 
00801                                                 MakeMechFall(mech);
00802                                         }
00803                                 }
00804                                 return side;
00805                         case 4:
00806                                 /* MP -1 */
00807                                 if(mudconf.btech_tankshield) {
00808                                         if(!Fallen(mech)) {
00809                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00810                                                 switch (MechMove(mech)) {
00811                                                 case MOVE_TRACK:
00812                                                         mech_notify(mech, MECHALL,
00813                                                                                 "One of your tracks is damaged!");
00814                                                         break;
00815                                                 case MOVE_WHEEL:
00816                                                         mech_notify(mech, MECHALL,
00817                                                                                 "One of your wheels is damaged!");
00818                                                         break;
00819                                                 case MOVE_HOVER:
00820                                                         mech_notify(mech, MECHALL,
00821                                                                                 "Your air skirt is damaged!");
00822                                                         break;
00823                                                 case MOVE_HULL:
00824                                                 case MOVE_SUB:
00825                                                 case MOVE_FOIL:
00826                                                         mech_notify(mech, MECHALL,
00827                                                                                 "Your craft suddenly slows!");
00828                                                         break;
00829                                                 }
00830                                                 LowerMaxSpeed(mech, MP1);
00831                                         }
00832                                 }
00833                                 return side;
00834                         case 5:
00835                                 /* MP -1 if Hovercraft */
00836                                 if(!Fallen(mech)) {
00837                                         if(MechMove(mech) == MOVE_HOVER) {
00838                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00839                                                 mech_notify(mech, MECHALL,
00840                                                                         "Your air skirt is damaged!");
00841                                                 LowerMaxSpeed(mech, MP1);
00842                                         }
00843                                 }
00844                                 return side;
00845                         case 6:
00846                         case 7:
00847                         case 8:
00848                         case 9:
00849                                 return side;
00850                         case 10:
00851                                 return (GetSectInt(mech, TURRET)) ? TURRET : side;
00852                         case 11:
00853                                 *iscritical = 1;
00854                                 /* Lock turret into place */
00855                                 if(GetSectInt(mech, TURRET)) {
00856                                         if(!(MechTankCritStatus(mech) & TURRET_LOCKED)) {
00857                                                 mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
00858                                                 MechTankCritStatus(mech) |= TURRET_LOCKED;
00859                                                 mech_notify(mech, MECHALL,
00860                                                                         "Your turret takes a direct hit and locks up!");
00861                                         }
00862                                         return TURRET;
00863                                 } else
00864                                         return side;
00865                         case 12:
00866                                 /* A Roll on Determining Critical Hits Table */
00867                                 if(crittable(mech, (GetSectInt(mech,
00868                                                                                            TURRET)) ? TURRET : side,
00869                                                          mudconf.btech_critlevel))
00870                                         *iscritical = 1;
00871                                 return (GetSectInt(mech, TURRET)) ? TURRET : side;
00872                         }
00873                 }
00874                 break;
00875         case CLASS_AERO:
00876                 switch (hitGroup) {
00877                 case FRONT:
00878                         switch (roll) {
00879                                 case 2:
00880                                         // Nose/Weapons
00881                                         return AERO_NOSE;
00882                                 case 3:
00883                                         // Nose/Sensors
00884                                         return AERO_NOSE;
00885                                 case 4:
00886                                         // Right Wing/Heat Sink
00887                                         return AERO_RWING;
00888                                 case 5:
00889                                         // Right Wing/Weapon
00890                                         return AERO_RWING;
00891                                 case 6:
00892                                         // Nose/Avionics
00893                                         return AERO_NOSE;
00894                                 case 7:
00895                                         // Nose/Control
00896                                         return AERO_NOSE;
00897                                 case 8:
00898                                         // Nose/FCS
00899                                         return AERO_NOSE;
00900                                 case 9:
00901                                         // Left Wing/Weapon
00902                                         return AERO_LWING;
00903                                 case 10:
00904                                         // Left Wing/Heat Sink
00905                                         return AERO_LWING;
00906                                 case 11:
00907                                         // Nose/Gear
00908                                         if(crittable(mech, AERO_NOSE, 90))
00909                                                 LoseWeapon(mech, AERO_NOSE);
00910                                         return AERO_NOSE;
00911                                 case 12:
00912                                         // Nose/Weapon
00913                                         return AERO_NOSE;
00914                         }
00915                         break;
00916                 case LEFTSIDE:
00917                         switch (roll) {
00918                                 case 2:
00919                                         // Nose/Weapon
00920                                         return AERO_NOSE;
00921                                 case 3:
00922                                         // Wing/Gear
00923                                         return AERO_LWING;
00924                                 case 4:
00925                                         // Nose/Senors
00926                                         return AERO_NOSE;
00927                                 case 5:
00928                                         // Nose/Crew
00929                                         return AERO_NOSE;
00930                                 case 6:
00931                                         // Wing/Weapons
00932                                         return AERO_LWING;
00933                                 case 7:
00934                                         // Wing/Avionics
00935                                         return AERO_LWING;
00936                                 case 8:
00937                                         // Wing/Bomb
00938                                         return AERO_LWING;
00939                                 case 9:
00940                                         // Aft/Control
00941                                         return AERO_AFT;
00942                                 case 10:
00943                                         // Aft/Engine
00944                                         return AERO_AFT;
00945                                 case 11:
00946                                         // Wing/Gear
00947                                         return AERO_LWING;
00948                                 case 12:
00949                                         // Aft/Weapon
00950                                         return AERO_AFT;
00951                         }
00952                 case RIGHTSIDE:
00953                         switch (roll) {
00954                                 case 2:
00955                                         // Nose/Weapon
00956                                         return AERO_NOSE;
00957                                 case 3:
00958                                         // Wing/Gear
00959                                         return AERO_RWING;
00960                                 case 4:
00961                                         // Nose/Sensors
00962                                         return AERO_NOSE;
00963                                 case 5:
00964                                         // Nose/Crew
00965                                         return AERO_NOSE;
00966                                 case 6:
00967                                         // Wing/Weapons
00968                                         return AERO_RWING;
00969                                 case 7:
00970                                         // Wing/Avionics
00971                                         return AERO_RWING;
00972                                 case 8:
00973                                         // Wing/Bomb
00974                                         return AERO_RWING;
00975                                 case 9:
00976                                         // Aft/Control
00977                                         return AERO_AFT;
00978                                 case 10:
00979                                         // Aft/Engine
00980                                         return AERO_AFT;
00981                                 case 11:
00982                                         // Wing/Gear
00983                                         return AERO_RWING;
00984                                 case 12:
00985                                         // Aft/Weapon
00986                                         return AERO_AFT;
00987                         }
00988                         break;
00989                 case BACK:
00990                         switch (roll) {
00991                                 case 2:
00992                                         // Aft/Weapon
00993                                         return AERO_AFT;
00994                                 case 3:
00995                                         // Aft/Heat Sink
00996                                         return AERO_AFT;
00997                                 case 4:
00998                                         // Right Wing/Fuel
00999                                         return AERO_RWING;
01000                                 case 5:
01001                                         // Right Wing/Weapon
01002                                         return AERO_RWING;
01003                                 case 6:
01004                                         // Aft/Engine
01005                                         return AERO_AFT;
01006                                 case 7:
01007                                         // Aft/Control
01008                                         return AERO_AFT;
01009                                 case 8:
01010                                         // Aft/Engine
01011                                         return AERO_AFT;
01012                                 case 9:
01013                                         // Left Wing/Weapon
01014                                         return AERO_LWING;
01015                                 case 10:
01016                                         // Left Wing/Fuel
01017                                         return AERO_LWING;
01018                                 case 11:
01019                                         // Aft/Heat Sink
01020                                         return AERO_AFT;
01021                                 case 12:
01022                                         // Aft/Weapon
01023                                         return AERO_AFT;
01024                         }
01025                 }
01026                 break;
01027         case CLASS_DS:
01028         case CLASS_SPHEROID_DS:
01029                 switch (hitGroup) {
01030                 case FRONT:
01031                         switch (roll) {
01032                         case 2:
01033                         case 12:
01034                                 if(crittable(mech, DS_NOSE, 30))
01035                                         ds_BridgeHit(mech);
01036                                 return DS_NOSE;
01037                         case 3:
01038                         case 11:
01039                                 if(crittable(mech, DS_NOSE, 50))
01040                                         LoseWeapon(mech, DS_NOSE);
01041                                 return DS_NOSE;
01042                         case 5:
01043                                 return DS_RWING;
01044                         case 6:
01045                         case 7:
01046                         case 8:
01047                                 return DS_NOSE;
01048                         case 9:
01049                                 return DS_LWING;
01050                         case 4:
01051                         case 10:
01052                                 return (Number(1, 2)) == 1 ? DS_LWING : DS_RWING;
01053                         }
01054                 case LEFTSIDE:
01055                 case RIGHTSIDE:
01056                         side = (hitGroup == LEFTSIDE) ? DS_LWING : DS_RWING;
01057                         if(Number(1, 2) == 2)
01058                                 SpheroidToRear(mech, side);
01059                         switch (roll) {
01060                         case 2:
01061                                 if(crittable(mech, DS_NOSE, 30))
01062                                         ds_BridgeHit(mech);
01063                                 return DS_NOSE;
01064                         case 3:
01065                         case 11:
01066                                 if(crittable(mech, side, 60))
01067                                         LoseWeapon(mech, side);
01068                                 return side;
01069                         case 4:
01070                         case 5:
01071                         case 6:
01072                         case 7:
01073                         case 8:
01074                         case 10:
01075                                 return side;
01076                         case 9:
01077                                 return DS_NOSE;
01078                         case 12:
01079                                 if(crittable(mech, side, 60))
01080                                         *iscritical = 1;
01081                                 return side;
01082                         }
01083                 case BACK:
01084                         switch (roll) {
01085                         case 2:
01086                         case 12:
01087                                 if(crittable(mech, DS_AFT, 60))
01088                                         *iscritical = 1;
01089                                 return DS_AFT;
01090                         case 3:
01091                         case 11:
01092                                 return DS_AFT;
01093                         case 4:
01094                         case 7:
01095                         case 10:
01096                                 if(crittable(mech, DS_AFT, 60))
01097                                         DestroyHeatSink(mech, DS_AFT);
01098                                 return DS_AFT;
01099                         case 5:
01100                                 hitloc = DS_RWING;
01101                                 SpheroidToRear(mech, hitloc);
01102                                 return hitloc;
01103                         case 6:
01104                         case 8:
01105                                 return DS_AFT;
01106                         case 9:
01107                                 hitloc = DS_LWING;
01108                                 SpheroidToRear(mech, hitloc);
01109                                 return hitloc;
01110                         }
01111                 }
01112                 break;
01113         case CLASS_VTOL:
01114                 switch (hitGroup) {
01115                 case LEFTSIDE:
01116                         switch (roll) {
01117                         case 2:
01118                                 hitloc = ROTOR;
01119                                 *iscritical = 1;
01120                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
01121                                 break;
01122                         case 3:
01123                                 *iscritical = 1;
01124                                 break;
01125                         case 4:
01126                         case 5:
01127                                 hitloc = ROTOR;
01128                                 DoVTOLRotorDamagedCrit(mech);
01129                                 break;
01130                         case 6:
01131                         case 7:
01132                         case 8:
01133                                 hitloc = LSIDE;
01134                                 break;
01135                         case 9:
01136                                 /*  Destroy Main Weapon but do not destroy armor */
01137                                 DestroyMainWeapon(mech);
01138                                 hitloc = 0;
01139                                 break;
01140                         case 10:
01141                         case 11:
01142                                 hitloc = ROTOR;
01143                                 DoVTOLRotorDamagedCrit(mech);
01144                                 break;
01145                         case 12:
01146                                 hitloc = ROTOR;
01147                                 *iscritical = 1;
01148                                 DoVTOLRotorDamagedCrit(mech);
01149                                 break;
01150                         }
01151                         break;
01152 
01153                 case RIGHTSIDE:
01154                         switch (roll) {
01155                         case 2:
01156                                 hitloc = ROTOR;
01157                                 *iscritical = 1;
01158                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
01159                                 break;
01160                         case 3:
01161                                 *iscritical = 1;
01162                                 break;
01163                         case 4:
01164                         case 5:
01165                                 hitloc = ROTOR;
01166                                 DoVTOLRotorDamagedCrit(mech);
01167                                 break;
01168                         case 6:
01169                         case 7:
01170                         case 8:
01171                                 hitloc = RSIDE;
01172                                 break;
01173                         case 9:
01174                                 /* Destroy Main Weapon but do not destroy armor */
01175                                 DestroyMainWeapon(mech);
01176                                 break;
01177                         case 10:
01178                         case 11:
01179                                 hitloc = ROTOR;
01180                                 DoVTOLRotorDamagedCrit(mech);
01181                                 break;
01182                         case 12:
01183                                 hitloc = ROTOR;
01184                                 *iscritical = 1;
01185                                 DoVTOLRotorDamagedCrit(mech);
01186                                 break;
01187                         }
01188                         break;
01189 
01190                 case FRONT:
01191                 case BACK:
01192                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01193 
01194                         switch (roll) {
01195                         case 2:
01196                                 hitloc = ROTOR;
01197                                 *iscritical = 1;
01198                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
01199                                 break;
01200                         case 3:
01201                                 hitloc = ROTOR;
01202                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
01203                                 break;
01204                         case 4:
01205                         case 5:
01206                                 hitloc = ROTOR;
01207                                 DoVTOLRotorDamagedCrit(mech);
01208                                 break;
01209                         case 6:
01210                         case 7:
01211                         case 8:
01212                         case 9:
01213                                 hitloc = side;
01214                                 break;
01215                         case 10:
01216                         case 11:
01217                                 hitloc = ROTOR;
01218                                 DoVTOLRotorDamagedCrit(mech);
01219                                 break;
01220                         case 12:
01221                                 hitloc = ROTOR;
01222                                 *iscritical = 1;
01223                                 DoVTOLRotorDamagedCrit(mech);
01224                                 break;
01225                         }
01226                         break;
01227                 }
01228 
01229                 break;
01230         case CLASS_VEH_NAVAL:
01231                 switch (hitGroup) {
01232                 case LEFTSIDE:
01233                         switch (roll) {
01234                         case 2:
01235                                 hitloc = LSIDE;
01236                                 if(crittable(mech, hitloc, 40))
01237                                         *iscritical = 1;
01238                                 break;
01239                         case 3:
01240                         case 4:
01241                         case 5:
01242                                 hitloc = LSIDE;
01243                                 break;
01244                         case 9:
01245                                 hitloc = LSIDE;
01246                                 break;
01247                         case 10:
01248                                 if(GetSectInt(mech, TURRET))
01249                                         hitloc = TURRET;
01250                                 else
01251                                         hitloc = LSIDE;
01252                                 break;
01253                         case 11:
01254                                 if(GetSectInt(mech, TURRET)) {
01255                                         hitloc = TURRET;
01256                                         if(crittable(mech, hitloc, 40))
01257                                                 *iscritical = 1;
01258                                 } else
01259                                         hitloc = LSIDE;
01260                                 break;
01261                         case 12:
01262                                 hitloc = LSIDE;
01263                                 *iscritical = 1;
01264                                 break;
01265                         }
01266                         break;
01267 
01268                 case RIGHTSIDE:
01269                         switch (roll) {
01270                         case 2:
01271                         case 12:
01272                                 hitloc = RSIDE;
01273                                 if(crittable(mech, hitloc, 40))
01274                                         *iscritical = 1;
01275                                 break;
01276                         case 3:
01277                         case 4:
01278                         case 5:
01279                         case 6:
01280                         case 7:
01281                         case 8:
01282                                 hitloc = RSIDE;
01283                                 break;
01284                         case 10:
01285                                 if(GetSectInt(mech, TURRET))
01286                                         hitloc = TURRET;
01287                                 else
01288                                         hitloc = RSIDE;
01289                                 break;
01290                         case 11:
01291                                 if(GetSectInt(mech, TURRET)) {
01292                                         hitloc = TURRET;
01293                                         if(crittable(mech, hitloc, 40))
01294                                                 *iscritical = 1;
01295                                 } else
01296                                         hitloc = RSIDE;
01297                                 break;
01298                         }
01299                         break;
01300 
01301                 case FRONT:
01302                 case BACK:
01303                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01304                         switch (roll) {
01305                         case 2:
01306                         case 12:
01307                                 hitloc = side;
01308                                 if(crittable(mech, hitloc, 40))
01309                                         *iscritical = 1;
01310                                 break;
01311                         case 3:
01312                                 hitloc = side;
01313                                 break;
01314                         case 4:
01315                                 hitloc = side;
01316                                 break;
01317                         case 5:
01318                                 hitloc = side;
01319                                 break;
01320                         case 6:
01321                         case 7:
01322                         case 8:
01323                         case 9:
01324                                 hitloc = side;
01325                                 break;
01326                         case 10:
01327                                 if(GetSectInt(mech, TURRET))
01328                                         hitloc = TURRET;
01329                                 else
01330                                         hitloc = side;
01331                                 break;
01332                         case 11:
01333                                 if(GetSectInt(mech, TURRET)) {
01334                                         hitloc = TURRET;
01335                                         *iscritical = 1;
01336                                 } else
01337                                         hitloc = side;
01338                                 break;
01339                         }
01340                         break;
01341                 }
01342                 break;
01343         }
01344         return (hitloc);
01345 }
01346 
01347 /* Do L3 FASA motive system crits */
01348 void DoMotiveSystemHit(MECH * mech, int wRollMod)
01349 {
01350         int wRoll;
01351         char strVhlTypeName[30];
01352 
01353         wRoll = Roll() + wRollMod;
01354 
01355         switch (MechMove(mech)) {
01356         case MOVE_TRACK:
01357                 strcpy(strVhlTypeName, "tank");
01358                 break;
01359         case MOVE_WHEEL:
01360                 strcpy(strVhlTypeName, "vehicle");
01361                 wRoll += 2;
01362                 break;
01363         case MOVE_HOVER:
01364                 strcpy(strVhlTypeName, "hovercraft");
01365                 wRoll += 4;
01366                 break;
01367         case MOVE_HULL:
01368                 strcpy(strVhlTypeName, "ship");
01369                 break;
01370         case MOVE_FOIL:
01371                 strcpy(strVhlTypeName, "hydrofoil");
01372                 wRoll += 4;
01373                 break;
01374         case MOVE_SUB:
01375                 strcpy(strVhlTypeName, "submarine");
01376                 break;
01377         default:
01378                 strcpy(strVhlTypeName, "weird unidentifiable toy (warn a wizard!)");
01379                 break;
01380         }
01381 
01382         if(wRoll < 8)                           /* no effect */
01383                 return;
01384 
01385         mech_notify(mech, MECHALL, "%ch%cyCRITICAL HIT!%c");
01386 
01387         if(wRoll < 10) {                        /* minor effect */
01388                 MechPilotSkillBase(mech) += 1;
01389 
01390                 if(Fallen(mech))
01391                         mech_notify(mech, MECHALL,
01392                                                 "%cr%chYour destroyed motive system takes another hit!%cn");
01393                 else
01394                         mech_printf(mech, MECHALL,
01395                                                 "%%cr%%chYour motive system takes a minor hit, making it harder to control your %s!%%cn",
01396                                                 strVhlTypeName);
01397 
01398                 if(MechSpeed(mech) != 0.0)
01399                         MechLOSBroadcast(mech, "wobbles slightly.");
01400         } else if(wRoll < 12) {         /* moderate effect */
01401                 MechPilotSkillBase(mech) += 2;
01402 
01403                 if(Fallen(mech))
01404                         mech_notify(mech, MECHALL,
01405                                                 "%cr%chYour destroyed motive system takes another hit!%cn");
01406                 else
01407                         mech_printf(mech, MECHALL,
01408                                                 "%%cr%%chYour motive system takes a moderate hit, slowing you down and making it harder to control your %s!%%cn",
01409                                                 strVhlTypeName);
01410 
01411                 if(MechSpeed(mech) != 0.0)
01412                         MechLOSBroadcast(mech, "wobbles violently.");
01413 
01414                 LowerMaxSpeed(mech, MP1);
01415                 correct_speed(mech);
01416         } else {
01417                 if(Fallen(mech))
01418                         mech_notify(mech, MECHALL,
01419                                                 "%cr%chYour destroyed motive system takes another hit!%cn");
01420                 else
01421                         mech_printf(mech, MECHALL,
01422                                                 "%%cr%%chYour motive system is destroyed! Your %s can no longer move!%%cn",
01423                                                 strVhlTypeName);
01424 
01425                 if(MechSpeed(mech) > 0)
01426                         MechLOSBroadcast(mech,
01427                                                          "shakes violently then begins to slow down.");
01428 
01429                 SetMaxSpeed(mech, 0.0);
01430                 MakeMechFall(mech);
01431                 correct_speed(mech);
01432         }
01433 
01434 }
01435 
01436 int FindAdvFasaVehicleHitLocation(MECH * mech, int hitGroup,
01437                                                                   int *iscritical, int *isrear)
01438 {
01439         int roll, hitloc = 0;
01440         int side;
01441 
01442         *iscritical = 0;
01443         roll = Roll();
01444 
01445         if(MechStatus(mech) & COMBAT_SAFE)
01446                 return 0;
01447 
01448         if(MechDugIn(mech) && GetSectInt(mech, TURRET) && Number(1, 100) >= 42)
01449                 return TURRET;
01450 
01451         rollstat.hitrolls[roll - 2]++;
01452         rollstat.tothrolls++;
01453 
01454         switch (MechType(mech)) {
01455         case CLASS_VEH_GROUND:
01456                 switch (hitGroup) {
01457                 case LEFTSIDE:
01458                 case RIGHTSIDE:
01459                         side = (hitGroup == LEFTSIDE ? LSIDE : RSIDE);
01460 
01461                         switch (roll) {
01462                         case 2:
01463                                 hitloc = side;
01464                                 *iscritical = 1;
01465                                 break;
01466                         case 3:
01467                                 hitloc = side;
01468                                 if(crittable(mech, hitloc, mudconf.btech_critlevel))
01469                                         DoMotiveSystemHit(mech, 0);
01470                                 break;
01471                         case 4:
01472                                 hitloc = side;
01473                                 break;
01474                         case 5:
01475                                 hitloc = FSIDE;
01476                                 break;
01477                         case 6:
01478                         case 7:
01479                         case 8:
01480                                 hitloc = side;
01481                                 break;
01482                         case 9:
01483                                 hitloc = BSIDE;
01484                                 break;
01485                         case 10:
01486                         case 11:
01487                                 hitloc = CHECK_ZERO_LOC(mech, TURRET, side);
01488                                 break;
01489                         case 12:
01490                                 hitloc = CHECK_ZERO_LOC(mech, TURRET, side);
01491                                 *iscritical = 1;
01492                                 break;
01493                         }
01494                         break;
01495 
01496                 case FRONT:
01497                 case BACK:
01498                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01499 
01500                         switch (roll) {
01501                         case 2:
01502                                 hitloc = side;
01503                                 *iscritical = 1;
01504                                 break;
01505                         case 3:
01506                                 hitloc = side;
01507 
01508                                 if(crittable(mech, hitloc, mudconf.btech_critlevel))
01509                                         DoMotiveSystemHit(mech, 0);
01510                                 break;
01511                         case 4:
01512                                 hitloc = side;
01513                                 break;
01514                         case 5:
01515                                 hitloc = (hitGroup == FRONT ? RSIDE : LSIDE);
01516                                 break;
01517                         case 6:
01518                         case 7:
01519                         case 8:
01520                                 hitloc = side;
01521                                 break;
01522                         case 9:
01523                                 hitloc = (hitGroup == FRONT ? LSIDE : RSIDE);
01524                                 break;
01525                         case 10:
01526                         case 11:
01527                                 hitloc =
01528                                         CHECK_ZERO_LOC(mech, TURRET,
01529                                                                    (hitGroup == FRONT ? LSIDE : RSIDE));
01530                                 break;
01531                         case 12:
01532                                 hitloc =
01533                                         CHECK_ZERO_LOC(mech, TURRET,
01534                                                                    (hitGroup == FRONT ? LSIDE : RSIDE));
01535                                 *iscritical = 1;
01536                                 break;
01537                         }
01538                         break;
01539                 }
01540                 break;
01541 
01542         case CLASS_VTOL:
01543                 switch (hitGroup) {
01544                 case LEFTSIDE:
01545                 case RIGHTSIDE:
01546                         side = (hitGroup == LEFTSIDE ? LSIDE : RSIDE);
01547 
01548                         switch (roll) {
01549                         case 2:
01550                                 hitloc = side;
01551                                 *iscritical = 1;
01552                                 break;
01553                         case 3:
01554                         case 4:
01555                                 hitloc = side;
01556                                 break;
01557                         case 5:
01558                                 hitloc = FSIDE;
01559                                 break;
01560                         case 6:
01561                         case 7:
01562                         case 8:
01563                                 hitloc = side;
01564                                 break;
01565                         case 9:
01566                                 hitloc = BSIDE;
01567                                 break;
01568                         case 10:
01569                         case 11:
01570                                 hitloc = ROTOR;
01571                                 break;
01572                         case 12:
01573                                 hitloc = ROTOR;
01574                                 *iscritical = 1;
01575                                 break;
01576                         }
01577                         break;
01578 
01579                 case FRONT:
01580                 case BACK:
01581                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01582 
01583                         switch (roll) {
01584                         case 2:
01585                                 hitloc = side;
01586                                 *iscritical = 1;
01587                                 break;
01588                         case 3:
01589                                 hitloc = side;
01590                                 break;
01591                         case 4:
01592                                 hitloc = side;
01593                                 break;
01594                         case 5:
01595                                 hitloc = (hitGroup == FRONT ? RSIDE : LSIDE);
01596                                 break;
01597                         case 6:
01598                         case 7:
01599                         case 8:
01600                                 hitloc = side;
01601                                 break;
01602                         case 9:
01603                                 hitloc = (hitGroup == FRONT ? LSIDE : RSIDE);
01604                                 break;
01605                         case 10:
01606                         case 11:
01607                                 hitloc = ROTOR;
01608                                 break;
01609                         case 12:
01610                                 hitloc = ROTOR;
01611                                 *iscritical = 1;
01612                                 break;
01613                         }
01614                         break;
01615                 }
01616                 break;
01617         }
01618 
01619         if(!crittable(mech, hitloc, mudconf.btech_critlevel))
01620                 *iscritical = 0;
01621 
01622         return hitloc;
01623 }
01624 
01625 /* Use this when the unit is CRITPROOF because the other
01626  * hitlocation functions are screwy */
01627 int FindHitLocation_CritProof(MECH * mech, int hitGroup, int *iscritical,
01628                                                           int *isrear)
01629 {
01630         int roll, hitloc = 0;
01631         int side;
01632 
01633         roll = Roll();
01634 
01635         /* Since we're crit proof set this to 0 */
01636         *iscritical = 0;
01637 
01638         if(MechStatus(mech) & COMBAT_SAFE)
01639                 return 0;
01640 
01641         if(MechDugIn(mech) && GetSectOInt(mech, TURRET) && Number(1, 100) >= 42)
01642                 return TURRET;
01643 
01644         rollstat.hitrolls[roll - 2]++;
01645         rollstat.tothrolls++;
01646         switch (MechType(mech)) {
01647         case CLASS_BSUIT:
01648                 if((hitloc = get_bsuit_hitloc(mech)) < 0)
01649                         return Number(0, NUM_BSUIT_MEMBERS - 1);
01650         case CLASS_MW:
01651         case CLASS_MECH:
01652                 switch (hitGroup) {
01653                 case LEFTSIDE:
01654                         switch (roll) {
01655                         case 2:
01656                                 return LTORSO;
01657                         case 3:
01658                                 return LLEG;
01659                         case 4:
01660                         case 5:
01661                                 return LARM;
01662                         case 6:
01663                                 return LLEG;
01664                         case 7:
01665                                 return LTORSO;
01666                         case 8:
01667                                 return CTORSO;
01668                         case 9:
01669                                 return RTORSO;
01670                         case 10:
01671                                 return RARM;
01672                         case 11:
01673                                 return RLEG;
01674                         case 12:
01675                                 if(mudconf.btech_exile_stun_code)
01676                                         return ModifyHeadHit(hitGroup, mech);
01677                                 return HEAD;
01678                         }
01679                 case RIGHTSIDE:
01680                         switch (roll) {
01681                         case 2:
01682                                 return RTORSO;
01683                         case 3:
01684                                 return RLEG;
01685                         case 4:
01686                         case 5:
01687                                 return RARM;
01688                         case 6:
01689                                 return RLEG;
01690                         case 7:
01691                                 return RTORSO;
01692                         case 8:
01693                                 return CTORSO;
01694                         case 9:
01695                                 return LTORSO;
01696                         case 10:
01697                                 return LARM;
01698                         case 11:
01699                                 return LLEG;
01700                         case 12:
01701                                 if(mudconf.btech_exile_stun_code)
01702                                         return ModifyHeadHit(hitGroup, mech);
01703                                 return HEAD;
01704                         }
01705                 case FRONT:
01706                 case BACK:
01707                         switch (roll) {
01708                         case 2:
01709                                 return CTORSO;
01710                         case 3:
01711                         case 4:
01712                                 return RARM;
01713                         case 5:
01714                                 return RLEG;
01715                         case 6:
01716                                 return RTORSO;
01717                         case 7:
01718                                 return CTORSO;
01719                         case 8:
01720                                 return LTORSO;
01721                         case 9:
01722                                 return LLEG;
01723                         case 10:
01724                         case 11:
01725                                 return LARM;
01726                         case 12:
01727                                 if(mudconf.btech_exile_stun_code)
01728                                         return ModifyHeadHit(hitGroup, mech);
01729                                 return HEAD;
01730                         }
01731                 }
01732                 break;
01733         case CLASS_VEH_GROUND:
01734                 switch (hitGroup) {
01735                 case LEFTSIDE:
01736                         switch (roll) {
01737                         case 2:
01738                         case 12:
01739                                 return LSIDE;
01740                         case 3:
01741                         case 4:
01742                         case 5:
01743                         case 6:
01744                         case 7:
01745                         case 8:
01746                         case 9:
01747                                 return LSIDE;
01748                         case 10:
01749                                 return (GetSectInt(mech, TURRET)) ? TURRET : LSIDE;
01750                         case 11:
01751                                 if(GetSectInt(mech, TURRET)) {
01752                                         return TURRET;
01753                                 } else
01754                                         return LSIDE;
01755                         }
01756                         break;
01757                 case RIGHTSIDE:
01758                         switch (roll) {
01759                         case 2:
01760                         case 12:
01761                                 return RSIDE;
01762                         case 3:
01763                         case 4:
01764                         case 5:
01765                         case 6:
01766                         case 7:
01767                         case 8:
01768                         case 9:
01769                                 return RSIDE;
01770                         case 10:
01771                                 return (GetSectInt(mech, TURRET)) ? TURRET : RSIDE;
01772                         case 11:
01773                                 if(GetSectInt(mech, TURRET)) {
01774                                         return TURRET;
01775                                 } else
01776                                         return RSIDE;
01777                                 break;
01778                         }
01779                         break;
01780 
01781                 case FRONT:
01782                 case BACK:
01783                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01784                         switch (roll) {
01785                         case 2:
01786                         case 12:
01787                                 return side;
01788                         case 3:
01789                         case 4:
01790                         case 5:
01791                         case 6:
01792                         case 7:
01793                         case 8:
01794                         case 9:
01795                                 return side;
01796                         case 10:
01797                                 return (GetSectInt(mech, TURRET)) ? TURRET : side;
01798                         case 11:
01799                                 if(GetSectInt(mech, TURRET)) {
01800                                         return TURRET;
01801                                 } else
01802                                         return side;
01803                         }
01804                 }
01805                 break;
01806         case CLASS_AERO:
01807                 switch (hitGroup) {
01808                 case FRONT:
01809                         switch (roll) {
01810                         case 2:
01811                         case 12:
01812                         case 3:
01813                         case 11:
01814                                 return AERO_NOSE;
01815                         case 4:
01816                         case 10:
01817                         case 5:
01818                                 return AERO_RWING;
01819                         case 9:
01820                                 return AERO_LWING;
01821                         case 6:
01822                         case 7:
01823                         case 8:
01824                                 return AERO_NOSE;
01825                         }
01826                         break;
01827                 case LEFTSIDE:
01828                 case RIGHTSIDE:
01829                         side = ((hitGroup == LEFTSIDE) ? AERO_LWING : AERO_RWING);
01830                         switch (roll) {
01831                         case 2:
01832                         case 12:
01833                                 return AERO_AFT;
01834                         case 3:
01835                         case 11:
01836                                 return side;
01837                         case 4:
01838                         case 10:
01839                                 return AERO_AFT;
01840                         case 5:
01841                         case 9:
01842                                 return AERO_NOSE;
01843                         case 6:
01844                         case 8:
01845                                 return side;
01846                         case 7:
01847                             return side;
01848                         }
01849                         break;
01850                 case BACK:
01851                         switch (roll) {
01852                         case 2:
01853                         case 12:
01854                                 return AERO_AFT;
01855                         case 3:
01856                         case 11:
01857                         case 4:
01858                         case 7:
01859                         case 10:
01860                         case 5:
01861                                 return AERO_RWING;
01862                         case 9:
01863                                 return AERO_LWING;
01864                         case 6:
01865                         case 8:
01866                                 return AERO_AFT;
01867                         }
01868                 }
01869                 break;
01870         case CLASS_DS:
01871         case CLASS_SPHEROID_DS:
01872                 switch (hitGroup) {
01873                 case FRONT:
01874                         switch (roll) {
01875                         case 2:
01876                         case 12:
01877                                 return DS_NOSE;
01878                         case 3:
01879                         case 11:
01880                                 return DS_NOSE;
01881                         case 5:
01882                                 return DS_RWING;
01883                         case 6:
01884                         case 7:
01885                         case 8:
01886                                 return DS_NOSE;
01887                         case 9:
01888                                 return DS_LWING;
01889                         case 4:
01890                         case 10:
01891                                 return (Number(1, 2)) == 1 ? DS_LWING : DS_RWING;
01892                         }
01893                 case LEFTSIDE:
01894                 case RIGHTSIDE:
01895                         side = (hitGroup == LEFTSIDE) ? DS_LWING : DS_RWING;
01896                         if(Number(1, 2) == 2)
01897                                 SpheroidToRear(mech, side);
01898                         switch (roll) {
01899                         case 2:
01900                                 return DS_NOSE;
01901                         case 3:
01902                         case 11:
01903                                 return side;
01904                         case 4:
01905                         case 5:
01906                         case 6:
01907                         case 7:
01908                         case 8:
01909                         case 10:
01910                                 return side;
01911                         case 9:
01912                                 return DS_NOSE;
01913                         case 12:
01914                                 return side;
01915                         }
01916                 case BACK:
01917                         switch (roll) {
01918                         case 2:
01919                         case 12:
01920                                 return DS_AFT;
01921                         case 3:
01922                         case 11:
01923                                 return DS_AFT;
01924                         case 4:
01925                         case 7:
01926                         case 10:
01927                                 return DS_AFT;
01928                         case 5:
01929                                 hitloc = DS_RWING;
01930                                 SpheroidToRear(mech, hitloc);
01931                                 return hitloc;
01932                         case 6:
01933                         case 8:
01934                                 return DS_AFT;
01935                         case 9:
01936                                 hitloc = DS_LWING;
01937                                 SpheroidToRear(mech, hitloc);
01938                                 return hitloc;
01939                         }
01940                 }
01941                 break;
01942         case CLASS_VTOL:
01943                 switch (hitGroup) {
01944                 case LEFTSIDE:
01945                         switch (roll) {
01946                         case 2:
01947                                 hitloc = ROTOR;
01948                                 break;
01949                         case 3:
01950                         case 4:
01951                                 hitloc = ROTOR;
01952                                 break;
01953                         case 5:
01954                         case 6:
01955                         case 7:
01956                         case 8:
01957                         case 9:
01958                                 hitloc = LSIDE;
01959                                 break;
01960                         case 10:
01961                         case 11:
01962                                 hitloc = ROTOR;
01963                                 break;
01964                         case 12:
01965                                 hitloc = ROTOR;
01966                                 break;
01967                         }
01968                         break;
01969 
01970                 case RIGHTSIDE:
01971                         switch (roll) {
01972                         case 2:
01973                                 hitloc = ROTOR;
01974                                 break;
01975                         case 3:
01976                         case 4:
01977                                 hitloc = ROTOR;
01978                                 break;
01979                         case 5:
01980                         case 6:
01981                         case 7:
01982                         case 8:
01983                         case 9:
01984                                 hitloc = RSIDE;
01985                                 break;
01986                         case 10:
01987                         case 11:
01988                                 hitloc = ROTOR;
01989                                 break;
01990                         case 12:
01991                                 hitloc = ROTOR;
01992                                 break;
01993                         }
01994                         break;
01995 
01996                 case FRONT:
01997                 case BACK:
01998                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
01999                         switch (roll) {
02000                         case 2:
02001                                 hitloc = ROTOR;
02002                                 break;
02003                         case 3:
02004                         case 4:
02005                                 hitloc = ROTOR;
02006                                 break;
02007                         case 5:
02008                         case 6:
02009                         case 7:
02010                         case 8:
02011                         case 9:
02012                                 hitloc = side;
02013                                 break;
02014                         case 10:
02015                         case 11:
02016                                 hitloc = ROTOR;
02017                                 break;
02018                         case 12:
02019                                 hitloc = ROTOR;
02020                                 break;
02021                         }
02022                         break;
02023                 }
02024                 break;
02025         case CLASS_VEH_NAVAL:
02026                 switch (hitGroup) {
02027                 case LEFTSIDE:
02028                         switch (roll) {
02029                         case 2:
02030                                 hitloc = LSIDE;
02031                                 break;
02032                         case 3:
02033                         case 4:
02034                         case 5:
02035                                 hitloc = LSIDE;
02036                                 break;
02037                         case 9:
02038                                 hitloc = LSIDE;
02039                                 break;
02040                         case 10:
02041                                 if(GetSectInt(mech, TURRET))
02042                                         hitloc = TURRET;
02043                                 else
02044                                         hitloc = LSIDE;
02045                                 break;
02046                         case 11:
02047                                 if(GetSectInt(mech, TURRET)) {
02048                                         hitloc = TURRET;
02049                                 } else
02050                                         hitloc = LSIDE;
02051                                 break;
02052                         case 12:
02053                                 hitloc = LSIDE;
02054                                 break;
02055                         }
02056                         break;
02057 
02058                 case RIGHTSIDE:
02059                         switch (roll) {
02060                         case 2:
02061                         case 12:
02062                                 hitloc = RSIDE;
02063                                 break;
02064                         case 3:
02065                         case 4:
02066                         case 5:
02067                         case 6:
02068                         case 7:
02069                         case 8:
02070                                 hitloc = RSIDE;
02071                                 break;
02072                         case 10:
02073                                 if(GetSectInt(mech, TURRET))
02074                                         hitloc = TURRET;
02075                                 else
02076                                         hitloc = RSIDE;
02077                                 break;
02078                         case 11:
02079                                 if(GetSectInt(mech, TURRET)) {
02080                                         hitloc = TURRET;
02081                                 } else
02082                                         hitloc = RSIDE;
02083                                 break;
02084                         }
02085                         break;
02086 
02087                 case FRONT:
02088                 case BACK:
02089                         switch (roll) {
02090                         case 2:
02091                         case 12:
02092                                 hitloc = FSIDE;
02093                                 break;
02094                         case 3:
02095                                 hitloc = FSIDE;
02096                                 break;
02097                         case 4:
02098                                 hitloc = FSIDE;
02099                                 break;
02100                         case 5:
02101                                 hitloc = FSIDE;
02102                                 break;
02103                         case 6:
02104                         case 7:
02105                         case 8:
02106                         case 9:
02107                                 hitloc = FSIDE;
02108                                 break;
02109                         case 10:
02110                                 if(GetSectInt(mech, TURRET))
02111                                         hitloc = TURRET;
02112                                 else
02113                                         hitloc = FSIDE;
02114                                 break;
02115                         case 11:
02116                                 if(GetSectInt(mech, TURRET)) {
02117                                         hitloc = TURRET;
02118                                 } else
02119                                         hitloc = FSIDE;
02120                                 break;
02121                         }
02122                         break;
02123                 }
02124                 break;
02125         }
02126         return (hitloc);
02127 }
02128 
02129 int FindHitLocation(MECH * mech, int hitGroup, int *iscritical, int *isrear)
02130 {
02131         int roll, hitloc = 0;
02132         int side;
02133 
02134         roll = Roll();
02135 
02136         /* We have a varying set of crit charts we can use, so let's see what's been config'd */
02137         /* We call the FindHitLocation_CritProof after the adv fasa hit loc function because
02138          * it already has a check built in for critproof (lookup crittable), the others don't */
02139         switch (MechType(mech)) {
02140         case CLASS_VTOL:
02141                 if(mudconf.btech_fasaadvvtolcrit)
02142                         return FindAdvFasaVehicleHitLocation(mech, hitGroup,
02143                                                                                                  iscritical, isrear);
02144                 else if(MechSpecials(mech) & CRITPROOF_TECH)
02145                         return FindHitLocation_CritProof(mech, hitGroup, iscritical,
02146                                                                                          isrear);
02147                 else if(mudconf.btech_fasacrit)
02148                         return FindFasaHitLocation(mech, hitGroup, iscritical, isrear);
02149                 break;
02150         case CLASS_VEH_GROUND:
02151                 if(mudconf.btech_fasaadvvhlcrit)
02152                         return FindAdvFasaVehicleHitLocation(mech, hitGroup,
02153                                                                                                  iscritical, isrear);
02154                 else if(MechSpecials(mech) & CRITPROOF_TECH)
02155                         return FindHitLocation_CritProof(mech, hitGroup, iscritical,
02156                                                                                          isrear);
02157                 else if(mudconf.btech_fasacrit)
02158                         return FindFasaHitLocation(mech, hitGroup, iscritical, isrear);
02159                 break;
02160         default:
02161                 if(MechSpecials(mech) & CRITPROOF_TECH)
02162                         return FindHitLocation_CritProof(mech, hitGroup, iscritical,
02163                                                                                          isrear);
02164                 else if(mudconf.btech_fasacrit)
02165                         return FindFasaHitLocation(mech, hitGroup, iscritical, isrear);
02166                 break;
02167         }
02168 
02169         if(MechStatus(mech) & COMBAT_SAFE)
02170                 return 0;
02171         if(MechDugIn(mech) && GetSectOInt(mech, TURRET) && Number(1, 100) >= 42)
02172                 return TURRET;
02173         rollstat.hitrolls[roll - 2]++;
02174         rollstat.tothrolls++;
02175         switch (MechType(mech)) {
02176         case CLASS_BSUIT:
02177                 if((hitloc = get_bsuit_hitloc(mech)) < 0)
02178                         return Number(0, NUM_BSUIT_MEMBERS - 1);
02179         case CLASS_MW:
02180         case CLASS_MECH:
02181                 switch (hitGroup) {
02182                 case LEFTSIDE:
02183                         switch (roll) {
02184                         case 2:
02185                                 if(crittable(mech, LTORSO, 60))
02186                                         *iscritical = 1;
02187                                 return LTORSO;
02188                         case 3:
02189                                 return LLEG;
02190                         case 4:
02191                         case 5:
02192                                 return LARM;
02193                         case 6:
02194                                 return LLEG;
02195                         case 7:
02196                                 return LTORSO;
02197                         case 8:
02198                                 return CTORSO;
02199                         case 9:
02200                                 return RTORSO;
02201                         case 10:
02202                                 return RARM;
02203                         case 11:
02204                                 return RLEG;
02205                         case 12:
02206                                 if(mudconf.btech_exile_stun_code)
02207                                         return ModifyHeadHit(hitGroup, mech);
02208                                 return HEAD;
02209                         }
02210                 case RIGHTSIDE:
02211                         switch (roll) {
02212                         case 2:
02213                                 if(crittable(mech, RTORSO, 60))
02214                                         *iscritical = 1;
02215                                 return RTORSO;
02216                         case 3:
02217                                 return RLEG;
02218                         case 4:
02219                         case 5:
02220                                 return RARM;
02221                         case 6:
02222                                 return RLEG;
02223                         case 7:
02224                                 return RTORSO;
02225                         case 8:
02226                                 return CTORSO;
02227                         case 9:
02228                                 return LTORSO;
02229                         case 10:
02230                                 return LARM;
02231                         case 11:
02232                                 return LLEG;
02233                         case 12:
02234                                 if(mudconf.btech_exile_stun_code)
02235                                         return ModifyHeadHit(hitGroup, mech);
02236                                 return HEAD;
02237                         }
02238                 case FRONT:
02239                 case BACK:
02240                         switch (roll) {
02241                         case 2:
02242                                 if(crittable(mech, CTORSO, 60))
02243                                         *iscritical = 1;
02244                                 return CTORSO;
02245                         case 3:
02246                         case 4:
02247                                 return RARM;
02248                         case 5:
02249                                 return RLEG;
02250                         case 6:
02251                                 return RTORSO;
02252                         case 7:
02253                                 return CTORSO;
02254                         case 8:
02255                                 return LTORSO;
02256                         case 9:
02257                                 return LLEG;
02258                         case 10:
02259                         case 11:
02260                                 return LARM;
02261                         case 12:
02262                                 if(mudconf.btech_exile_stun_code)
02263                                         return ModifyHeadHit(hitGroup, mech);
02264                                 return HEAD;
02265                         }
02266                 }
02267                 break;
02268         case CLASS_VEH_GROUND:
02269                 switch (hitGroup) {
02270                 case LEFTSIDE:
02271                         switch (roll) {
02272                         case 2:
02273                         case 12:
02274                                 if(crittable(mech, LSIDE, 40))
02275                                         *iscritical = 1;
02276                                 return LSIDE;
02277                         case 3:
02278                         case 4:
02279                         case 5:
02280                         case 6:
02281                         case 7:
02282                         case 8:
02283                         case 9:
02284                                 return LSIDE;
02285                         case 10:
02286                                 return (GetSectInt(mech, TURRET)) ? TURRET : LSIDE;
02287                         case 11:
02288                                 if(GetSectInt(mech, TURRET)) {
02289                                         if(crittable(mech, TURRET, 50))
02290                                                 *iscritical = 1;
02291                                         return TURRET;
02292                                 } else
02293                                         return LSIDE;
02294                         }
02295                         break;
02296                 case RIGHTSIDE:
02297                         switch (roll) {
02298                         case 2:
02299                         case 12:
02300                                 if(crittable(mech, RSIDE, 40))
02301                                         *iscritical = 1;
02302                                 return RSIDE;
02303                         case 3:
02304                         case 4:
02305                         case 5:
02306                         case 6:
02307                         case 7:
02308                         case 8:
02309                         case 9:
02310                                 return RSIDE;
02311                         case 10:
02312                                 return (GetSectInt(mech, TURRET)) ? TURRET : RSIDE;
02313                         case 11:
02314                                 if(GetSectInt(mech, TURRET)) {
02315                                         if(crittable(mech, TURRET, 50))
02316                                                 *iscritical = 1;
02317                                         return TURRET;
02318                                 } else
02319                                         return RSIDE;
02320                                 break;
02321                         }
02322                         break;
02323 
02324                 case FRONT:
02325                 case BACK:
02326                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
02327                         switch (roll) {
02328                         case 2:
02329                         case 12:
02330                                 if(crittable(mech, FSIDE, 40))
02331                                         *iscritical = 1;
02332                                 return side;
02333                         case 3:
02334                         case 4:
02335                         case 5:
02336                         case 6:
02337                         case 7:
02338                         case 8:
02339                         case 9:
02340                                 return side;
02341                         case 10:
02342                                 return (GetSectInt(mech, TURRET)) ? TURRET : side;
02343                         case 11:
02344                                 if(GetSectInt(mech, TURRET)) {
02345                                         if(crittable(mech, TURRET, 50))
02346                                                 *iscritical = 1;
02347                                         return TURRET;
02348                                 } else
02349                                         return side;
02350                         }
02351                 }
02352                 break;
02353         case CLASS_AERO:
02354                 switch (hitGroup) {
02355                 case FRONT:
02356                         switch (roll) {
02357                         case 2:
02358                         case 12:
02359                         case 3:
02360                         case 11:
02361                                 if(crittable(mech, AERO_NOSE, 90))
02362                                         LoseWeapon(mech, AERO_NOSE);
02363                                 return AERO_NOSE;
02364                         case 4:
02365                         case 10:
02366                         case 5:
02367                                 return AERO_RWING;
02368                         case 9:
02369                                 return AERO_LWING;
02370                         case 6:
02371                         case 7:
02372                         case 8:
02373                                 return AERO_NOSE;
02374                         }
02375                         break;
02376                 case LEFTSIDE:
02377                 case RIGHTSIDE:
02378                         side = ((hitGroup == LEFTSIDE) ? AERO_LWING : AERO_RWING);
02379                         switch (roll) {
02380                         case 2:
02381                         case 12:
02382                                 if(crittable(mech, AERO_AFT, 99))
02383                                         *iscritical = 1;
02384                                 return AERO_AFT;
02385                         case 3:
02386                         case 11:
02387                                 if(crittable(mech, side, 99))
02388                                         LoseWeapon(mech, side);
02389                                 return side;
02390                         case 4:
02391                         case 10:
02392                                 if(crittable(mech, AERO_AFT, 90))
02393                                         DestroyHeatSink(mech, AERO_AFT);
02394                                 return AERO_AFT;
02395                         case 5:
02396                         case 9:
02397                                 return AERO_NOSE;
02398                         case 6:
02399                         case 8:
02400                                 return side;
02401                         case 7:
02402                             return side;
02403                         }
02404                         break;
02405                 case BACK:
02406                         switch (roll) {
02407                         case 2:
02408                         case 12:
02409                                 if(crittable(mech, AERO_AFT, 90))
02410                                         *iscritical = 1;
02411                                 return AERO_AFT;
02412                         case 3:
02413                         case 11:
02414                         case 4:
02415                         case 7:
02416                         case 10:
02417                         case 5:
02418                                 return AERO_RWING;
02419                         case 9:
02420                                 return AERO_LWING;
02421                         case 6:
02422                         case 8:
02423                                 return AERO_AFT;
02424                         }
02425                 }
02426                 break;
02427         case CLASS_DS:
02428         case CLASS_SPHEROID_DS:
02429                 switch (hitGroup) {
02430                 case FRONT:
02431                         switch (roll) {
02432                         case 2:
02433                         case 12:
02434                                 if(crittable(mech, DS_NOSE, 30))
02435                                         ds_BridgeHit(mech);
02436                                 return DS_NOSE;
02437                         case 3:
02438                         case 11:
02439                                 if(crittable(mech, DS_NOSE, 50))
02440                                         LoseWeapon(mech, DS_NOSE);
02441                                 return DS_NOSE;
02442                         case 5:
02443                                 return DS_RWING;
02444                         case 6:
02445                         case 7:
02446                         case 8:
02447                                 return DS_NOSE;
02448                         case 9:
02449                                 return DS_LWING;
02450                         case 4:
02451                         case 10:
02452                                 return (Number(1, 2)) == 1 ? DS_LWING : DS_RWING;
02453                         }
02454                 case LEFTSIDE:
02455                 case RIGHTSIDE:
02456                         side = (hitGroup == LEFTSIDE) ? DS_LWING : DS_RWING;
02457                         if(Number(1, 2) == 2)
02458                                 SpheroidToRear(mech, side);
02459                         switch (roll) {
02460                         case 2:
02461                                 if(crittable(mech, DS_NOSE, 30))
02462                                         ds_BridgeHit(mech);
02463                                 return DS_NOSE;
02464                         case 3:
02465                         case 11:
02466                                 if(crittable(mech, side, 60))
02467                                         LoseWeapon(mech, side);
02468                                 return side;
02469                         case 4:
02470                         case 5:
02471                         case 6:
02472                         case 7:
02473                         case 8:
02474                         case 10:
02475                                 return side;
02476                         case 9:
02477                                 return DS_NOSE;
02478                         case 12:
02479                                 if(crittable(mech, side, 60))
02480                                         *iscritical = 1;
02481                                 return side;
02482                         }
02483                 case BACK:
02484                         switch (roll) {
02485                         case 2:
02486                         case 12:
02487                                 if(crittable(mech, DS_AFT, 60))
02488                                         *iscritical = 1;
02489                                 return DS_AFT;
02490                         case 3:
02491                         case 11:
02492                                 return DS_AFT;
02493                         case 4:
02494                         case 7:
02495                         case 10:
02496                                 if(crittable(mech, DS_AFT, 60))
02497                                         DestroyHeatSink(mech, DS_AFT);
02498                                 return DS_AFT;
02499                         case 5:
02500                                 hitloc = DS_RWING;
02501                                 SpheroidToRear(mech, hitloc);
02502                                 return hitloc;
02503                         case 6:
02504                         case 8:
02505                                 return DS_AFT;
02506                         case 9:
02507                                 hitloc = DS_LWING;
02508                                 SpheroidToRear(mech, hitloc);
02509                                 return hitloc;
02510                         }
02511                 }
02512                 break;
02513         case CLASS_VTOL:
02514                 switch (hitGroup) {
02515                 case LEFTSIDE:
02516                         switch (roll) {
02517                         case 2:
02518                                 hitloc = ROTOR;
02519                                 *iscritical = 1;
02520                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
02521                                 break;
02522                         case 3:
02523                         case 4:
02524                                 hitloc = ROTOR;
02525                                 DoVTOLRotorDamagedCrit(mech);
02526                                 break;
02527                         case 5:
02528                         case 6:
02529                         case 7:
02530                         case 8:
02531                         case 9:
02532                                 hitloc = LSIDE;
02533                                 break;
02534                         case 10:
02535                         case 11:
02536                                 hitloc = ROTOR;
02537                                 DoVTOLRotorDamagedCrit(mech);
02538                                 break;
02539                         case 12:
02540                                 hitloc = ROTOR;
02541                                 *iscritical = 1;
02542                                 DoVTOLRotorDamagedCrit(mech);
02543                                 break;
02544                         }
02545                         break;
02546 
02547                 case RIGHTSIDE:
02548                         switch (roll) {
02549                         case 2:
02550                                 hitloc = ROTOR;
02551                                 *iscritical = 1;
02552                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
02553                                 break;
02554                         case 3:
02555                         case 4:
02556                                 hitloc = ROTOR;
02557                                 DoVTOLRotorDamagedCrit(mech);
02558                                 break;
02559                         case 5:
02560                         case 6:
02561                         case 7:
02562                         case 8:
02563                         case 9:
02564                                 hitloc = RSIDE;
02565                                 break;
02566                         case 10:
02567                         case 11:
02568                                 hitloc = ROTOR;
02569                                 DoVTOLRotorDamagedCrit(mech);
02570                                 break;
02571                         case 12:
02572                                 hitloc = ROTOR;
02573                                 *iscritical = 1;
02574                                 DoVTOLRotorDamagedCrit(mech);
02575                                 break;
02576                         }
02577                         break;
02578 
02579                 case FRONT:
02580                 case BACK:
02581                         side = (hitGroup == FRONT ? FSIDE : BSIDE);
02582                         switch (roll) {
02583                         case 2:
02584                                 hitloc = ROTOR;
02585                                 *iscritical = 1;
02586                                 DoVTOLRotorDestroyedCrit(mech, NULL, 1);
02587                                 break;
02588                         case 3:
02589                         case 4:
02590                                 hitloc = ROTOR;
02591                                 DoVTOLRotorDamagedCrit(mech);
02592                                 break;
02593                         case 5:
02594                         case 6:
02595                         case 7:
02596                         case 8:
02597                         case 9:
02598                                 hitloc = side;
02599                                 break;
02600                         case 10:
02601                         case 11:
02602                                 hitloc = ROTOR;
02603                                 DoVTOLRotorDamagedCrit(mech);
02604                                 break;
02605                         case 12:
02606                                 hitloc = ROTOR;
02607                                 *iscritical = 1;
02608                                 DoVTOLRotorDamagedCrit(mech);
02609                                 break;
02610                         }
02611                         break;
02612                 }
02613                 break;
02614         case CLASS_VEH_NAVAL:
02615                 switch (hitGroup) {
02616                 case LEFTSIDE:
02617                         switch (roll) {
02618                         case 2:
02619                                 hitloc = LSIDE;
02620                                 if(crittable(mech, hitloc, 40))
02621                                         *iscritical = 1;
02622                                 break;
02623                         case 3:
02624                         case 4:
02625                         case 5:
02626                                 hitloc = LSIDE;
02627                                 break;
02628                         case 9:
02629                                 hitloc = LSIDE;
02630                                 break;
02631                         case 10:
02632                                 if(GetSectInt(mech, TURRET))
02633                                         hitloc = TURRET;
02634                                 else
02635                                         hitloc = LSIDE;
02636                                 break;
02637                         case 11:
02638                                 if(GetSectInt(mech, TURRET)) {
02639                                         hitloc = TURRET;
02640                                         if(crittable(mech, hitloc, 40))
02641                                                 *iscritical = 1;
02642                                 } else
02643                                         hitloc = LSIDE;
02644                                 break;
02645                         case 12:
02646                                 hitloc = LSIDE;
02647                                 *iscritical = 1;
02648                                 break;
02649                         }
02650                         break;
02651 
02652                 case RIGHTSIDE:
02653                         switch (roll) {
02654                         case 2:
02655                         case 12:
02656                                 hitloc = RSIDE;
02657                                 if(crittable(mech, hitloc, 40))
02658                                         *iscritical = 1;
02659                                 break;
02660                         case 3:
02661                         case 4:
02662                         case 5:
02663                         case 6:
02664                         case 7:
02665                         case 8:
02666                                 hitloc = RSIDE;
02667                                 break;
02668                         case 10:
02669                                 if(GetSectInt(mech, TURRET))
02670                                         hitloc = TURRET;
02671                                 else
02672                                         hitloc = RSIDE;
02673                                 break;
02674                         case 11:
02675                                 if(GetSectInt(mech, TURRET)) {
02676                                         hitloc = TURRET;
02677                                         if(crittable(mech, hitloc, 40))
02678                                                 *iscritical = 1;
02679                                 } else
02680                                         hitloc = RSIDE;
02681                                 break;
02682                         }
02683                         break;
02684 
02685                 case FRONT:
02686                 case BACK:
02687                         switch (roll) {
02688                         case 2:
02689                         case 12:
02690                                 hitloc = FSIDE;
02691                                 if(crittable(mech, hitloc, 40))
02692                                         *iscritical = 1;
02693                                 break;
02694                         case 3:
02695                                 hitloc = FSIDE;
02696                                 break;
02697                         case 4:
02698                                 hitloc = FSIDE;
02699                                 break;
02700                         case 5:
02701                                 hitloc = FSIDE;
02702                                 break;
02703                         case 6:
02704                         case 7:
02705                         case 8:
02706                         case 9:
02707                                 hitloc = FSIDE;
02708                                 break;
02709                         case 10:
02710                                 if(GetSectInt(mech, TURRET))
02711                                         hitloc = TURRET;
02712                                 else
02713                                         hitloc = FSIDE;
02714                                 break;
02715                         case 11:
02716                                 if(GetSectInt(mech, TURRET)) {
02717                                         hitloc = TURRET;
02718                                         *iscritical = 1;
02719                                 } else
02720                                         hitloc = FSIDE;
02721                                 break;
02722                         }
02723                         break;
02724                 }
02725                 break;
02726         }
02727         return (hitloc);
02728 }
02729 
02730 int FindAreaHitGroup(MECH * mech, MECH * target)
02731 {
02732         int quadr;
02733 
02734         quadr =
02735                 AcceptableDegree(FindBearing(MechFX(mech), MechFY(mech),
02736                                                                          MechFX(target),
02737                                                                          MechFY(target)) - MechFacing(target));
02738 #if 1
02739         if((quadr >= 135) && (quadr <= 225))
02740                 return FRONT;
02741         if((quadr < 45) || (quadr > 315))
02742                 return BACK;
02743         if((quadr >= 45) && (quadr < 135))
02744                 return LEFTSIDE;
02745         return RIGHTSIDE;
02746 #else
02747         /* These are 'official' BT arcs */
02748         if(quadr >= 120 && quadr <= 240)
02749                 return FRONT;
02750         if(quadr < 30 || quadr > 330)
02751                 return BACK;
02752         if(quadr >= 30 && quadr < 120)
02753                 return LEFTSIDE;
02754         return RIGHTSIDE;
02755 #endif
02756 }
02757 
02758 int FindTargetHitLoc(MECH *mech, MECH *target, int *isrear, int *iscritical) {
02759 
02760     int hitGroup;
02761 
02762     *iscritical = 0;
02763     hitGroup = FindAreaHitGroup(mech, target);
02764 
02765     if (hitGroup == BACK) {
02766         *isrear = 1;
02767     }
02768 
02769     if (MechType(target) == CLASS_MECH && (MechStatus(target) & PARTIAL_COVER)) {
02770         return FindPunchLocation(target, hitGroup);
02771     }
02772 
02773     if (MechType(mech) == CLASS_MW && MechType(target) == CLASS_MECH &&
02774             MechZ(mech) <= MechZ(target)) {
02775         return FindKickLocation(target, hitGroup);
02776     }
02777 
02778     if (MechType(target) == CLASS_MECH && ((MechType(mech) == CLASS_BSUIT &&
02779               MechSwarmTarget(mech) == target->mynum))) {
02780         return FindSwarmHitLocation(iscritical, isrear);
02781     }
02782 
02783     return FindHitLocation(target, hitGroup, iscritical, isrear);
02784 }
02785 
02786 int findNARCHitLoc(MECH * mech, MECH * hitMech, int *tIsRearHit)
02787 {
02788         int tIsRear = 0;
02789         int tIsCritical = 0;
02790         int wHitLoc = FindTargetHitLoc(mech, hitMech, &tIsRear, &tIsCritical);
02791 
02792         while (GetSectInt(hitMech, wHitLoc) <= 0) {
02793                 wHitLoc = TransferTarget(hitMech, wHitLoc);
02794                 if(wHitLoc < 0)
02795                         return -1;
02796         }
02797 
02798         *tIsRearHit = 0;
02799         if(tIsRear) {
02800                 if(MechType(hitMech) == CLASS_MECH)
02801                         *tIsRearHit = 1;
02802                 else if(wHitLoc == FSIDE)
02803                         wHitLoc = BSIDE;
02804         }
02805 
02806         return wHitLoc;
02807 }
02808 
02809 int FindTCHitLoc(MECH * mech, MECH * target, int *isrear, int *iscritical)
02810 {
02811         int hitGroup;
02812 
02813         *isrear = 0;
02814         *iscritical = 0;
02815         hitGroup = FindAreaHitGroup(mech, target);
02816         if(hitGroup == BACK)
02817                 *isrear = 1;
02818         if(MechAimType(mech) == MechType(target) && Number(1, 6) >= 3)
02819                 switch (MechType(target)) {
02820                 case CLASS_MECH:
02821                 case CLASS_MW:
02822                         switch (MechAim(mech)) {
02823                         case RARM:
02824                                 if(hitGroup != LEFTSIDE)
02825                                         return RARM;
02826                                 break;
02827                         case LARM:
02828                                 if(hitGroup != RIGHTSIDE)
02829                                         return LARM;
02830                                 break;
02831                         case RLEG:
02832                                 if(hitGroup != LEFTSIDE &&
02833                                    !(MechStatus(target) & PARTIAL_COVER))
02834                                         return RLEG;
02835                                 break;
02836                         case LLEG:
02837                                 if(hitGroup != RIGHTSIDE &&
02838                                    !(MechStatus(target) & PARTIAL_COVER))
02839                                         return LLEG;
02840                                 break;
02841                         case RTORSO:
02842                                 if(hitGroup != LEFTSIDE)
02843                                         return RTORSO;
02844                                 break;
02845                         case LTORSO:
02846                                 if(hitGroup != RIGHTSIDE)
02847                                         return LTORSO;
02848                                 break;
02849                         case CTORSO:
02850 
02851 /*        if (hitGroup != LEFTSIDE && hitGroup != RIGHTSIDE) */
02852                                 return CTORSO;
02853                         case HEAD:
02854                                 if(Immobile(target))
02855                                         return HEAD;
02856                         }
02857                         break;
02858                 case CLASS_AERO:
02859                 case CLASS_DS:
02860                         switch (MechAim(mech)) {
02861                         case AERO_NOSE:
02862                                 if(hitGroup != BACK)
02863                                         return AERO_NOSE;
02864                                 break;
02865                         case AERO_LWING:
02866                                 if(hitGroup != RIGHTSIDE)
02867                                         return AERO_LWING;
02868                                 break;
02869                         case AERO_RWING:
02870                                 if(hitGroup != LEFTSIDE)
02871                                         return AERO_RWING;
02872                                 break;
02873                         case AERO_AFT:
02874                                 if(hitGroup != FRONT)
02875                                         return AERO_AFT;
02876                                 break;
02877                         }
02878                 case CLASS_VEH_GROUND:
02879                 case CLASS_VEH_NAVAL:
02880                 case CLASS_VTOL:
02881                         switch (MechAim(mech)) {
02882                         case RSIDE:
02883                                 if(hitGroup != LEFTSIDE)
02884                                         return (RSIDE);
02885                                 break;
02886                         case LSIDE:
02887                                 if(hitGroup != RIGHTSIDE)
02888                                         return (LSIDE);
02889                                 break;
02890                         case FSIDE:
02891                                 if(hitGroup != BACK)
02892                                         return (FSIDE);
02893                                 break;
02894                         case BSIDE:
02895                                 if(hitGroup != FRONT)
02896                                         return (BSIDE);
02897                                 break;
02898                         case TURRET:
02899                                 return (TURRET);
02900                                 break;
02901                         }
02902                         break;
02903                 }
02904         if(MechType(target) == CLASS_MECH && (MechStatus(target) & PARTIAL_COVER))
02905                 return FindPunchLocation(target, hitGroup);
02906         return FindHitLocation(target, hitGroup, iscritical, isrear);
02907 }
02908 
02909 int FindAimHitLoc(MECH * mech, MECH * target, int *isrear, int *iscritical)
02910 {
02911         int hitGroup;
02912 
02913         *isrear = 0;
02914         *iscritical = 0;
02915         hitGroup = FindAreaHitGroup(mech, target);
02916         if(hitGroup == BACK)
02917                 *isrear = 1;
02918         if(MechType(target) == CLASS_MECH || MechType(target) == CLASS_MW)
02919                 switch (MechAim(mech)) {
02920                 case RARM:
02921                         if(hitGroup != LEFTSIDE)
02922                                 return (RARM);
02923                         break;
02924                 case LARM:
02925                         if(hitGroup != RIGHTSIDE)
02926                                 return (LARM);
02927                         break;
02928                 case RLEG:
02929                         if(hitGroup != LEFTSIDE && !(MechStatus(target) & PARTIAL_COVER))
02930                                 return (RLEG);
02931                         break;
02932                 case LLEG:
02933                         if(hitGroup != RIGHTSIDE && !(MechStatus(target) & PARTIAL_COVER))
02934                                 return (LLEG);
02935                         break;
02936                 case RTORSO:
02937                         if(hitGroup != LEFTSIDE)
02938                                 return (RTORSO);
02939                         break;
02940                 case LTORSO:
02941                         if(hitGroup != RIGHTSIDE)
02942                                 return (LTORSO);
02943                         break;
02944                 case CTORSO:
02945                         return (CTORSO);
02946                 case HEAD:
02947                         return (HEAD);
02948         } else if(is_aero(target))
02949                 return MechAim(mech);
02950         else
02951                 switch (MechAim(mech)) {
02952                 case RSIDE:
02953                         if(hitGroup != LEFTSIDE)
02954                                 return (RSIDE);
02955                         break;
02956                 case LSIDE:
02957                         if(hitGroup != RIGHTSIDE)
02958                                 return (LSIDE);
02959                         break;
02960                 case FSIDE:
02961                         if(hitGroup != BACK)
02962                                 return (FSIDE);
02963                         break;
02964                 case BSIDE:
02965                         if(hitGroup != FRONT)
02966                                 return (BSIDE);
02967                         break;
02968                 case TURRET:
02969                         return (TURRET);
02970                         break;
02971                 }
02972 
02973         if(MechType(target) == CLASS_MECH && (MechStatus(target) & PARTIAL_COVER))
02974                 return FindPunchLocation(target, hitGroup);
02975         return FindHitLocation(target, hitGroup, iscritical, isrear);
02976 }

Generated on Mon May 28 04:25:22 2007 for BattletechMUX by  doxygen 1.4.7