00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <math.h>
00012 #include "config.h"
00013 #include "externs.h"
00014 #include "db.h"
00015 #include "mech.h"
00016 #include "btmacros.h"
00017 #include "mech.events.h"
00018 #include "mech.sensor.h"
00019 #include "failures.h"
00020 #include "p.econ_cmds.h"
00021 #include "p.mech.update.h"
00022 #include "p.bsuit.h"
00023 #include "autopilot.h"
00024 #include "p.mech.combat.h"
00025 #include "p.mech.combat.misc.h"
00026 #include "p.mech.damage.h"
00027 #include "p.mech.utils.h"
00028 #include "p.btechstats.h"
00029 #include "p.mechrep.h"
00030 #include "p.mech.restrict.h"
00031 #include "p.eject.h"
00032 #include "p.mech.pickup.h"
00033 #include "p.mech.tag.h"
00034 #include "p.mech.c3.h"
00035 #include "p.mech.c3i.h"
00036 #include "p.mech.enhanced.criticals.h"
00037 #include "p.mech.ammodump.h"
00038
00039 void correct_speed(MECH * mech)
00040 {
00041 float maxspeed = MMaxSpeed(mech);
00042 int neg = 1;
00043
00044 if(MechMaxSpeed(mech) < 0.0)
00045 MechMaxSpeed(mech) = 0.0;
00046 SetCargoWeight(mech);
00047 if(MechDesiredSpeed(mech) < -0.1) {
00048 maxspeed = maxspeed * 2.0 / 3.0;
00049 neg = -1;
00050 }
00051 if(fabs(MechDesiredSpeed(mech)) > maxspeed)
00052 MechDesiredSpeed(mech) = (float) maxspeed *neg;
00053
00054 if(fabs(MechSpeed(mech)) > maxspeed)
00055 MechSpeed(mech) = (float) maxspeed *neg;
00056 }
00057
00058 void explode_unit(MECH * wounded, MECH * attacker)
00059 {
00060 int j;
00061 MECH *target;
00062 dbref i, tmpnext;
00063 dbref from;
00064
00065 from = wounded->mynum;
00066
00067 SAFE_DOLIST(i, tmpnext, Contents(from)) {
00068 if(Good_obj(i) && Hardcode(i)) {
00069 if((target = getMech(i))) {
00070 if(MechType(target) == CLASS_BSUIT) {
00071 KillMechContentsIfIC(target->mynum);
00072 discard_mw(target);
00073 }
00074 }
00075 }
00076 }
00077
00078 KillMechContentsIfIC(wounded->mynum);
00079 for(j = 0; j < NUM_SECTIONS; j++) {
00080 if(GetSectOInt(wounded, j) && !SectIsDestroyed(wounded, j))
00081 DestroySection(wounded, attacker, wounded == attacker ? 0 : 1, j);
00082 }
00083 }
00084
00085 void NormalizeArmActuatorCrits(MECH * objMech, int wLoc, int wCritType)
00086 {
00087 switch (Special2I(wCritType)) {
00088 case SHOULDER_OR_HIP:
00089
00090 MechSections(objMech)[wLoc].basetohit = 4;
00091 break;
00092
00093 case UPPER_ACTUATOR:
00094 case LOWER_ACTUATOR:
00095
00096 MechSections(objMech)[wLoc].basetohit += 1;
00097 break;
00098 }
00099 }
00100
00101 void NormalizeLegActuatorCrits(MECH * objMech, int wLoc, int wCritType)
00102 {
00103 switch (Special2I(wCritType)) {
00104 case SHOULDER_OR_HIP:
00105
00106
00107
00108
00109
00110 DivideMaxSpeed(objMech, 2);
00111 MechPilotSkillBase(objMech) += 2;
00112 break;
00113
00114 case UPPER_ACTUATOR:
00115 case LOWER_ACTUATOR:
00116 case HAND_OR_FOOT_ACTUATOR:
00117
00118
00119
00120
00121
00122 LowerMaxSpeed(objMech, MP1);
00123 MechSections(objMech)[wLoc].basetohit += 1;
00124 MechPilotSkillBase(objMech) += 1;
00125 break;
00126 }
00127 }
00128
00129 void NormalizeLocActuatorCrits(MECH * objMech, int wLoc)
00130 {
00131 int wCritType;
00132 int tIsArm = 0;
00133 int tHasShoulderOrHipCrit = 0;
00134 int i;
00135
00136 if(!MechIsQuad(objMech) && ((wLoc == LARM) || (wLoc == RARM)))
00137 tIsArm = 1;
00138
00139
00140 MechSections(objMech)[wLoc].basetohit = 0;
00141
00142
00143 for(i = 0; i < NUM_CRITICALS; i++) {
00144 wCritType = GetPartType(objMech, wLoc, i);
00145
00146 if(PartIsDestroyed(objMech, wLoc, i)) {
00147 if(IsSpecial(wCritType)) {
00148 switch (Special2I(wCritType)) {
00149 case SHOULDER_OR_HIP:
00150 tHasShoulderOrHipCrit = 1;
00151
00152 if(tIsArm)
00153 NormalizeArmActuatorCrits(objMech, wLoc, wCritType);
00154 else
00155 NormalizeLegActuatorCrits(objMech, wLoc, wCritType);
00156
00157 break;
00158 }
00159 }
00160 }
00161
00162 if(tHasShoulderOrHipCrit)
00163 break;
00164 }
00165
00166
00167 if(!tHasShoulderOrHipCrit) {
00168
00169 for(i = 0; i < NUM_CRITICALS; i++) {
00170 wCritType = GetPartType(objMech, wLoc, i);
00171
00172 if(PartIsDestroyed(objMech, wLoc, i)) {
00173
00174 if(IsSpecial(wCritType)) {
00175
00176 switch (Special2I(wCritType)) {
00177 case UPPER_ACTUATOR:
00178 case LOWER_ACTUATOR:
00179 case HAND_OR_FOOT_ACTUATOR:
00180 if(tIsArm)
00181 NormalizeArmActuatorCrits(objMech, wLoc,
00182 wCritType);
00183 else
00184 NormalizeLegActuatorCrits(objMech, wLoc,
00185 wCritType);
00186
00187 break;
00188 }
00189 }
00190 }
00191 }
00192 }
00193
00194 correct_speed(objMech);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 void NormalizeAllActuatorCrits(MECH * objMech)
00204 {
00205 int wLegsDestroyed = CountDestroyedLegs(objMech);
00206 int wMaxTemplateSpeed = 0;
00207
00208
00209 MechPilotSkillBase(objMech) = 0;
00210
00211 SetMaxSpeed(objMech, TemplateMaxSpeed(objMech));
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 if(MechSpecials2(objMech) & HDGYRO_TECH) {
00222 if(MechCritStatus2(objMech) & HDGYRO_DAMAGED) {
00223 if(MechCritStatus(objMech) & GYRO_DAMAGED) {
00224 MechPilotSkillBase(objMech) += 3;
00225 } else {
00226 MechPilotSkillBase(objMech) += 2;
00227 }
00228 }
00229
00230 } else if(MechCritStatus(objMech) & GYRO_DAMAGED)
00231 MechPilotSkillBase(objMech) += 3;
00232
00233
00234
00235
00236
00237 if(wLegsDestroyed > 0) {
00238 if(MechIsQuad(objMech)) {
00239 MechPilotSkillBase(objMech) += 2;
00240
00241 switch (wLegsDestroyed) {
00242 case 1:
00243 LowerMaxSpeed(objMech, MP1);
00244 break;
00245
00246 case 2:
00247 SetMaxSpeed(objMech, MP1);
00248 MechPilotSkillBase(objMech) += 5;
00249 break;
00250
00251 case 3:
00252 case 4:
00253 SetMaxSpeed(objMech, 0.0);
00254 MakeMechFall(objMech);;
00255 break;
00256 }
00257 } else {
00258 if(wLegsDestroyed == 1) {
00259 SetMaxSpeed(objMech, MP1);
00260 MechPilotSkillBase(objMech) += 5;
00261 } else {
00262 SetMaxSpeed(objMech, 0.0);
00263 MechPilotSkillBase(objMech) += 10;
00264 MakeMechFall(objMech);
00265 }
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 if(!IsLegDestroyed(objMech, LARM))
00312 NormalizeLocActuatorCrits(objMech, LARM);
00313
00314 if(!IsLegDestroyed(objMech, RARM))
00315 NormalizeLocActuatorCrits(objMech, RARM);
00316
00317 if(!IsLegDestroyed(objMech, LLEG))
00318 NormalizeLocActuatorCrits(objMech, LLEG);
00319
00320 if(!IsLegDestroyed(objMech, RLEG))
00321 NormalizeLocActuatorCrits(objMech, RLEG);
00322
00323
00324
00325
00326
00327 if(MechCritStatus(objMech) & HIP_DESTROYED) {
00328 SetMaxSpeed(objMech, 0.0);
00329 MakeMechFall(objMech);
00330 }
00331
00332 correct_speed(objMech);
00333 }
00334
00335 int handleWeaponCrit(MECH * attacker, MECH * wounded, int hitloc,
00336 int critHit, int critType, int LOS)
00337 {
00338 int wMaxCrits, wFirstCrit, wWeapDestroyed = 0;
00339 int wAmmoSection, wAmmoCritSlot;
00340 int damage, loop;
00341 char locname[30];
00342 char msgbuf[MBUF_SIZE];
00343
00344 ArmorStringFromIndex(hitloc, locname, MechType(wounded),
00345 MechMove(wounded));
00346
00347
00348 wMaxCrits = GetWeaponCrits(wounded, Weapon2I(critType));
00349
00350
00351 wFirstCrit =
00352 FindFirstWeaponCrit(wounded, hitloc, critHit, 0, critType, wMaxCrits);
00353
00354
00355 if(wFirstCrit != -1) {
00356 wWeapDestroyed = (PartIsNonfunctional(wounded, hitloc, wFirstCrit)
00357 || (PartTempNuke(wounded, hitloc,
00358 wFirstCrit) == FAIL_DESTROYED));
00359 }
00360
00361
00362 if((MechWeapons[Weapon2I(critType)].special & GAUSS) && !wWeapDestroyed) {
00363 mech_printf(wounded, MECHALL,
00364 "Your %s has been destroyed!",
00365 &MechWeapons[Weapon2I(critType)].name[3]);
00366
00367 mech_printf(wounded, MECHALL,
00368 "It explodes for %d points damage.",
00369 MechWeapons[Weapon2I(critType)].explosiondamage);
00370
00371 if(LOS && wounded != attacker && attacker)
00372 mech_notify(attacker, MECHALL,
00373 "Your target is covered in a large electrical discharge.");
00374
00375 DestroyWeapon(wounded, hitloc, critType, wFirstCrit, wMaxCrits,
00376 wMaxCrits);
00377
00378 if(attacker) {
00379 DamageMech(wounded, attacker, 0, -1, hitloc, 0, 0, 0,
00380 MechWeapons[Weapon2I(critType)].explosiondamage, -1, 7,
00381 -1, 0, 1);
00382 }
00383
00384 return 1;
00385 } else if(IsAMS(Weapon2I(critType))) {
00386 mech_printf(wounded, MECHALL,
00387 "Your %s has been destroyed!",
00388 &MechWeapons[Weapon2I(critType)].name[3]);
00389
00390 MechStatus(wounded) &= ~AMS_ENABLED;
00391 MechSpecials(wounded) &=
00392 ~(IS_ANTI_MISSILE_TECH | CL_ANTI_MISSILE_TECH);
00393 } else if(HotLoading(Weapon2I(critType), GetPartFireMode(wounded, hitloc, wFirstCrit)) && !wWeapDestroyed) {
00394 if(FindAmmoForWeapon(wounded, Weapon2I(critType), 0,
00395 &wAmmoSection, &wAmmoCritSlot) > 0) {
00396 damage = MechWeapons[Weapon2I(critType)].damage;
00397
00398 if(IsMissile(Weapon2I(critType)) ||
00399 IsArtillery(Weapon2I(critType))) {
00400 for(loop = 0; MissileHitTable[loop].key != -1; loop++) {
00401 if(MissileHitTable[loop].key == Weapon2I(critType)) {
00402 damage *= MissileHitTable[loop].num_missiles[10];
00403 break;
00404 }
00405 }
00406 }
00407
00408 mech_printf(wounded, MECHALL,
00409 "Your %s has been destroyed!",
00410 &MechWeapons[Weapon2I(critType)].name[3]);
00411
00412 mech_printf(wounded, MECHALL,
00413 "%%ch%%crYour hotloaded launcher explodes for %d points of damage!%%cn",
00414 damage);
00415
00416 if(LOS && wounded != attacker && attacker)
00417 MechLOSBroadcast(wounded,
00418 "loses a launcher in a brilliant explosion!");
00419
00420 DestroyWeapon(wounded, hitloc, critType, wFirstCrit, wMaxCrits,
00421 wMaxCrits);
00422
00423 if(attacker) {
00424 DamageMech(wounded, attacker, 0, -1, hitloc, 0, 0, 0,
00425 damage, -1, 7, -1, 0, 1);
00426 }
00427
00428 return 1;
00429 }
00430 } else if((GetPartAmmoMode(wounded, hitloc,
00431 wFirstCrit) & AC_INCENDIARY_MODE)
00432 && !wWeapDestroyed && WpnIsRecycling(wounded, hitloc, wFirstCrit)) {
00433
00434 if(FindAmmoForWeapon_sub(wounded, -1, -1, Weapon2I(critType),
00435 0, &wAmmoSection, &wAmmoCritSlot, 0,
00436 AC_INCENDIARY_MODE) > 0) {
00437
00438 mech_printf(wounded, MECHALL,
00439 "Your %s has been destroyed!",
00440 &MechWeapons[Weapon2I(critType)].name[3]);
00441
00442 mech_printf(wounded, MECHALL,
00443 "%%ch%%crThe incendiary ammunition in your launcher ignites for %d points of damage!%%cn",
00444 MechWeapons[Weapon2I(critType)].damage);
00445
00446 if(LOS && wounded != attacker && attacker) {
00447 sprintf(msgbuf,
00448 "'s %s is engulfed in a brilliant blue flame!",
00449 locname);
00450 MechLOSBroadcast(wounded, msgbuf);
00451 }
00452
00453 DestroyWeapon(wounded, hitloc, critType, wFirstCrit, wMaxCrits,
00454 wMaxCrits);
00455
00456 if(attacker) {
00457 DamageMech(wounded, attacker, 0, -1, hitloc, 0, 0, 0,
00458 MechWeapons[Weapon2I(critType)].damage, -1, 7, -1,
00459 0, 1);
00460
00461 return 1;
00462 }
00463 }
00464 }
00465
00466 return 0;
00467 }
00468
00469 void JamMainWeapon(MECH * mech)
00470 {
00471 unsigned char weaparray[MAX_WEAPS_SECTION];
00472 unsigned char weapdata[MAX_WEAPS_SECTION];
00473 int critical[MAX_WEAPS_SECTION];
00474 int count;
00475 int loop;
00476 int ii;
00477 int tempcrit;
00478 int maxcrit = 0;
00479 int maxloc = 0;
00480 int critfound = 0;
00481 int critnum = 0;
00482 unsigned char maxtype = 0;
00483
00484 for(loop = 0; loop < NUM_SECTIONS; loop++) {
00485 if(SectIsDestroyed(mech, loop))
00486 continue;
00487 count = FindWeapons(mech, loop, weaparray, weapdata, critical);
00488 if(count > 0) {
00489 for(ii = 0; ii < count; ii++) {
00490 if(!PartIsBroken(mech, loop, critical[ii])) {
00491
00492 tempcrit = rand();
00493 if(tempcrit > maxcrit) {
00494 critfound = 1;
00495 maxcrit = tempcrit;
00496 maxloc = loop;
00497 maxtype = weaparray[ii];
00498 critnum = critical[ii];
00499 }
00500 }
00501 }
00502 }
00503 }
00504
00505 if(critfound) {
00506 SetPartTempNuke(mech, maxloc, critnum, FAIL_DESTROYED);
00507 mech_printf(mech, MECHALL, "%%ch%%crYour %s is jammed!%%c",
00508 &MechWeapons[maxtype].name[3]);
00509 }
00510 }
00511
00512 void pickRandomWeapon(MECH * objMech, int wLoc, int *critNum, int wIgnoreJams)
00513 {
00514 int awCrits[MAX_WEAPS_SECTION];
00515 int wcWeaps = 0;
00516 int wIter;
00517
00518
00519
00520
00521
00522 for(wIter = 0; wIter < MAX_WEAPS_SECTION; wIter++) {
00523 if(IsWeapon(GetPartType(objMech, wLoc, wIter))) {
00524 if(!PartIsBroken(objMech, wLoc, wIter)) {
00525 if(!wIgnoreJams || (wIgnoreJams &&
00526 !PartTempNuke(objMech, wLoc, wIter))) {
00527 awCrits[wcWeaps] = wIter;
00528
00529 wcWeaps++;
00530 }
00531 }
00532 }
00533 }
00534
00535 if(wcWeaps <= 0) {
00536 *critNum = -1;
00537 return;
00538 }
00539
00540
00541
00542
00543
00544 *critNum = awCrits[Number(0, wcWeaps - 1)];
00545 }
00546
00547
00548
00549
00550 void limitSpeedToCruise(MECH * objMech)
00551 {
00552 int wMaxSpeed = 0;
00553
00554 wMaxSpeed = MMaxSpeed(objMech);
00555
00556 if(MechMove(objMech) == MOVE_VTOL)
00557 wMaxSpeed =
00558 sqrt((float) wMaxSpeed * wMaxSpeed -
00559 MechVerticalSpeed(objMech) * MechVerticalSpeed(objMech));
00560
00561 if(WalkingSpeed(wMaxSpeed) < MechDesiredSpeed(objMech))
00562 MechDesiredSpeed(objMech) = WalkingSpeed(wMaxSpeed) - 0.1;
00563 }
00564
00565 void DoVehicleStablizerCrit(MECH * objMech, int wLoc)
00566 {
00567
00568
00569
00570
00571
00572
00573
00574 char strLocName[30];
00575
00576 ArmorStringFromIndex(wLoc, strLocName, MechType(objMech),
00577 MechMove(objMech));
00578
00579 if(MechSections(objMech)[wLoc].config & STABILIZERS_DESTROYED)
00580 mech_printf(objMech, MECHALL,
00581 "The destroyed weapon stabilizers in your %s take another hit!",
00582 strLocName);
00583 else {
00584 mech_printf(objMech, MECHALL,
00585 "The weapon stabilizers in your %s have been destroyed!",
00586 strLocName);
00587 MechSections(objMech)[wLoc].config |= STABILIZERS_DESTROYED;
00588 }
00589 }
00590
00591 void DoTurretLockCrit(MECH * objMech)
00592 {
00593
00594
00595
00596
00597 if(MechTankCritStatus(objMech) & TURRET_LOCKED) {
00598 mech_notify(objMech, MECHALL,
00599 "The shot pierces your armor yet fails to hit a critical system!");
00600 return;
00601 }
00602
00603 if(MechTankCritStatus(objMech) & TURRET_JAMMED)
00604 MechTankCritStatus(objMech) &= ~TURRET_JAMMED;
00605
00606 MechTankCritStatus(objMech) |= TURRET_LOCKED;
00607 mech_notify(objMech, MECHALL,
00608 "%ch%crThe shot destroys your turret rotation mechanism!%cn");
00609 }
00610
00611 void DoTurretJamCrit(MECH * objMech)
00612 {
00613
00614
00615
00616
00617
00618
00619 if(MechTankCritStatus(objMech) & TURRET_LOCKED) {
00620 mech_notify(objMech, MECHALL,
00621 "The shot pierces your armor yet fails to hit a critical system!");
00622 return;
00623 }
00624
00625 if(MechTankCritStatus(objMech) & TURRET_JAMMED) {
00626 DoTurretLockCrit(objMech);
00627 return;
00628 }
00629
00630 MechTankCritStatus(objMech) |= TURRET_JAMMED;
00631 mech_notify(objMech, MECHALL,
00632 "%ch%crYour turret gets jammed on its current facing!%cn");
00633 }
00634
00635 void DoWeaponJamCrit(MECH * objMech, int wLoc)
00636 {
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 int wWeapIdx = 0;
00648 int wCritType = 0;
00649 int wCritNum = 0;
00650
00651 if(SectIsDestroyed(objMech, wLoc))
00652 return;
00653
00654 pickRandomWeapon(objMech, wLoc, &wCritNum, 1);
00655
00656 if(wCritNum < 0) {
00657 mech_notify(objMech, MECHALL,
00658 "The shot pierces your armor yet fails to hit a critical system!");
00659 return;
00660 }
00661
00662 wCritType = GetPartType(objMech, wLoc, wCritNum);
00663 wWeapIdx = Weapon2I(wCritType);
00664
00665 if(wWeapIdx >= 0) {
00666 switch (MechWeapons[wWeapIdx].type) {
00667 case TBEAM:
00668 case TMISSILE:
00669 case TARTILLERY:
00670 wCritType = FAIL_SHORTED;
00671 mech_printf(objMech, MECHALL,
00672 "%%ch%%crThe shot causes your %s to temporarily short out!%%c",
00673 &MechWeapons[wWeapIdx].name[3]);
00674 break;
00675 case TAMMO:
00676 wCritType = FAIL_JAMMED;
00677 mech_printf(objMech, MECHALL,
00678 "%%ch%%crThe shot temporarily jams your %s!%%c",
00679 &MechWeapons[wWeapIdx].name[3]);
00680 break;
00681 default:
00682 wCritType = FAIL_SHORTED;
00683 mech_printf(objMech, MECHALL,
00684 "%%ch%%crThe shot causes your %s to temporarily short out!%%c",
00685 &MechWeapons[wWeapIdx].name[3]);
00686 break;
00687 }
00688
00689 SetPartTempNuke(objMech, wLoc, wCritNum, wCritType);
00690 SetRecyclePart(objMech, wLoc, wCritNum, Number(60, 120));
00691 }
00692 }
00693
00694 void DoWeaponDestroyedCrit(MECH * objAttacker, MECH * objMech, int wLoc,
00695 int LOS)
00696 {
00697
00698
00699
00700 int wWeapIdx = 0;
00701 int wCritNum = 0;
00702 int wCritType = 0;
00703 int firstCrit = 0;
00704
00705 if(SectIsDestroyed(objMech, wLoc))
00706 return;
00707
00708 pickRandomWeapon(objMech, wLoc, &wCritNum, 0);
00709
00710 if(wCritNum < 0) {
00711 mech_notify(objMech, MECHALL,
00712 "The shot pierces your armor yet fails to hit a critical system!");
00713 return;
00714 }
00715
00716 wCritType = GetPartType(objMech, wLoc, wCritNum);
00717 wWeapIdx = Weapon2I(wCritType);
00718
00719 if(handleWeaponCrit(objAttacker, objMech, wLoc, wCritNum, wCritType, LOS)) {
00720 return;
00721 }
00722
00723 if(wWeapIdx >= 0) {
00724 firstCrit = FindFirstWeaponCrit(objMech, wLoc, -1, 0, wCritType, 1);
00725
00726 DestroyWeapon(objMech, wLoc, wCritType, firstCrit, 1, 1);
00727 mech_printf(objMech, MECHALL,
00728 "%%ch%%crYour %s is destroyed!%%c",
00729 &MechWeapons[wWeapIdx].name[3]);
00730 }
00731 }
00732
00733 void DoTurretBlownOffCrit(MECH * objMech, MECH * objAttacker, int LOS)
00734 {
00735
00736
00737
00738
00739 if(SectIsDestroyed(objMech, TURRET))
00740 return;
00741
00742 mech_notify(objMech, MECHALL,
00743 "%ch%crThe shot pops your turret clear off its housing!%cn");
00744 MechLOSBroadcast(objMech, "'s turret flies off!");
00745 DestroySection(objMech, objAttacker, LOS, TURRET);
00746 }
00747
00748 void DoAmmunitionCrit(MECH * objMech, MECH * objAttacker, int wLoc, int LOS)
00749 {
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 int wTotalAmmoDamage = 0;
00761 int wTempDamage = 0;
00762 int wSecIter, wSlotIter;
00763 int wPartType = 0;
00764 int wWeapIdx;
00765
00766 for(wSecIter = 0; wSecIter <= 7; wSecIter++) {
00767 if(SectIsDestroyed(objMech, wSecIter))
00768 continue;
00769
00770 for(wSlotIter = CritsInLoc(objMech, wSecIter) - 1; wSlotIter >= 0;
00771 wSlotIter--) {
00772 wPartType = GetPartType(objMech, wSecIter, wSlotIter);
00773 wWeapIdx = Ammo2WeaponI(wPartType);
00774
00775 if(IsAmmo(wPartType) &&
00776 GetPartData(objMech, wSecIter, wSlotIter) &&
00777 (!(MechWeapons[wWeapIdx].special & GAUSS))) {
00778 wTempDamage =
00779 (FindMaxAmmoDamage(Ammo2WeaponI(wPartType)) *
00780 GetPartData(objMech, wSecIter, wSlotIter));
00781 wTotalAmmoDamage += wTempDamage;
00782
00783 SetPartData(objMech, wSecIter, wSlotIter, 0);
00784 }
00785 }
00786 }
00787
00788 if(wTotalAmmoDamage == 0) {
00789 DoWeaponDestroyedCrit(objAttacker, objMech, wLoc, LOS);
00790 return;
00791 }
00792
00793 mech_notify(objMech, MECHALL,
00794 "%ch%crOne of your ammo bins is struck causing a cascading explosion!%cn");
00795 MechLOSBroadcast(objMech, "has an internal ammo explosion!");
00796
00797 DamageMech(objMech, objAttacker, 0, -1, wLoc, 0, 0, 0,
00798 wTotalAmmoDamage, 0, 0, -1, 0, 1);
00799 }
00800
00801 void DoCargoInfantryCrit(MECH * objMech, int wLoc)
00802 {
00803
00804
00805
00806
00807
00808
00809
00810 mech_notify(objMech, MECHALL,
00811 "The shot pierces your armor yet fails to hit a critical system!");
00812 }
00813
00814 void DoVehicleEngineHit(MECH * objMech, MECH * objAttacker)
00815 {
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 if(Fallen(objMech)) {
00827 mech_notify(objMech, MECHALL,
00828 "Your destroyed engine takes another direct hit!");
00829 return;
00830 }
00831
00832 mech_notify(objMech, MECHALL, "%ch%crYour engine takes a direct hit!%cn");
00833
00834 if(MechType(objMech) == CLASS_VTOL) {
00835 if(!Landed(objMech)) {
00836 if(MechRTerrain(objMech) == GRASSLAND ||
00837 MechRTerrain(objMech) == ROAD ||
00838 MechRTerrain(objMech) == BUILDING) {
00839
00840 if(MadePilotSkillRoll(objMech,
00841 MechZ(objMech) -
00842 MechElevation(objMech))) {
00843 mech_notify(objMech, MECHALL, "You land safely!");
00844 MechStatus(objMech) |= LANDED;
00845 MechZ(objMech) = MechElevation(objMech);
00846 MechFZ(objMech) = ZSCALE * MechZ(objMech);
00847 SetMaxSpeed(objMech, 0.0);
00848 MechVerticalSpeed(objMech) = 0.0;
00849 }
00850 } else {
00851 mech_notify(objMech, MECHALL, "The ground rushes up to meet you!");
00852 mech_notify(objAttacker, MECHALL,
00853 "You knock the VTOL out of the sky!");
00854 MechLOSBroadcast(objMech, "falls from the sky!");
00855 MechFalls(objMech, MechsElevation(objMech), 0);
00856 }
00857 }
00858 } else {
00859 SetMaxSpeed(objMech, 0.0);
00860 MakeMechFall(objMech);
00861 }
00862 }
00863
00864 void DoVehicleFuelTankCrit(MECH * objMech, MECH * objAttacker)
00865 {
00866
00867
00868
00869
00870
00871
00872 if(!(MechSpecials(objMech) & ICE_TECH)) {
00873 DoVehicleEngineHit(objMech, objAttacker);
00874 return;
00875 }
00876
00877 mech_notify(objMech, MECHALL,
00878 "%ch%crYour fuel tank explodes in a ball of fire!%cn");
00879
00880 if(objMech != objAttacker)
00881 MechLOSBroadcast(objMech, "explodes in a ball of fire!");
00882
00883 MechZ(objMech) = MechElevation(objMech);
00884 MechFZ(objMech) = ZSCALE * MechZ(objMech);
00885 MechSpeed(objMech) = 0.0;
00886 MechVerticalSpeed(objMech) = 0.0;
00887 DestroyMech(objMech, objAttacker, 0);
00888 explode_unit(objMech, objAttacker);
00889 }
00890
00891 void DoVehicleCrewStunnedCrit(MECH * objMech)
00892 {
00893
00894
00895
00896
00897 MechTankCritStatus(objMech) |= CREW_STUNNED;
00898 mech_notify(objMech, MECHALL,
00899 "%ch%crThe shot resonates throughout the crew compartment, temporarily stunning you!%cn");
00900
00901 StunCrew(objMech);
00902 limitSpeedToCruise(objMech);
00903 }
00904
00905 void DoVehicleDriverCrit(MECH * objMech)
00906 {
00907
00908
00909
00910
00911 mech_notify(objMech, MECHALL,
00912 "%ch%crYour vehicle's driver takes a piece of shrapnel, making it harder to control the vehicle!%cn");
00913 MechPilotSkillBase(objMech) += 2;
00914 }
00915
00916 void DoVehicleSensorCrit(MECH * objMech)
00917 {
00918
00919
00920
00921
00922 mech_notify(objMech, MECHALL, "%ch%crYour sensor suite takes a hit!%cn");
00923 MechBTH(objMech) += 1;
00924 }
00925
00926 void DoVehicleCommanderHit(MECH * objMech)
00927 {
00928
00929
00930
00931
00932
00933 mech_notify(objMech, MECHALL,
00934 "%ch%crYour vehicle's commander takes a piece of shrapnel!%cn");
00935 MechPilotSkillBase(objMech) += 1;
00936 MechBTH(objMech) += 1;
00937
00938 DoVehicleCrewStunnedCrit(objMech);
00939 }
00940
00941 void DoVehicleCrewKilledCrit(MECH * objMech, MECH * objAttacker)
00942 {
00943
00944
00945
00946
00947
00948 mech_notify(objMech, MECHALL,
00949 "%ch%crThe shot ricochets around the crew compartment, instantly killing everyone!%cn");
00950 DestroyMech(objMech, objAttacker, 0);
00951 KillMechContentsIfIC(objMech->mynum);
00952
00953 if(MechSpeed(objMech) != 0.0)
00954 MechLOSBroadcast(objMech,
00955 "careens out of control and starts to slow!");
00956
00957 MakeMechFall(objMech);
00958 }
00959
00960 void DoVTOLCoPilotCrit(MECH * objMech)
00961 {
00962
00963
00964
00965
00966 mech_notify(objMech, MECHALL,
00967 "%ch%crYour VTOL's pilot takes a piece of shrapnel, making it harder to aim your weapons!%cn");
00968 MechBTH(objMech) += 1;
00969 }
00970
00971 void DoVTOLPilotHit(MECH * objMech)
00972 {
00973
00974
00975
00976
00977
00978
00979 mech_notify(objMech, MECHALL,
00980 "%ch%crYour VTOL's copilot takes a piece of shrapnel, making it harder to control the VTOL!%cn");
00981 MechPilotSkillBase(objMech) += 2;
00982
00983
00984 }
00985
00986 void DoVTOLRotorDestroyedCrit(MECH * objMech, MECH * objAttacker, int LOS)
00987 {
00988
00989
00990
00991
00992
00993 if(SectIsDestroyed(objMech, ROTOR))
00994 return;
00995
00996 mech_notify(objMech, MECHALL,
00997 "%ch%crThe shot hits your fragile rotor mechanism!%cn");
00998 MechLOSBroadcast(objMech, "'s rotor snaps into several parts!");
00999 DestroySection(objMech, objAttacker, LOS, ROTOR);
01000
01001 if(!objAttacker) {
01002 mech_notify(objMech, MECHALL, "Your rotor has been destroyed!");
01003 MechLOSBroadcast(objMech, "'s rotor has been destroyed!");
01004 }
01005 }
01006
01007 void DoVTOLRotorDamagedCrit(MECH * objMech)
01008 {
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 if(MMaxSpeed(objMech) <= MP1) {
01019 DoVTOLRotorDestroyedCrit(objMech, NULL, 1);
01020 return;
01021 }
01022
01023 mech_notify(objMech, MECHALL, "Your rotor is damaged!");
01024
01025 if(!Fallen(objMech))
01026 LowerMaxSpeed(objMech, MP1);
01027
01028 }
01029
01030 void DoVTOLTailRotorDamagedCrit(MECH * objMech)
01031 {
01032
01033
01034
01035
01036
01037 if(MechTankCritStatus(objMech) & TAIL_ROTOR_DESTROYED)
01038 mech_notify(objMech, MECHALL,
01039 "Your damaged tail rotor suffers more damage!");
01040 else {
01041 MechTankCritStatus(objMech) |= TAIL_ROTOR_DESTROYED;
01042 mech_notify(objMech, MECHALL,
01043 "%ch%crYour tail rotor is damaged, slowing you down!%cn");
01044
01045 limitSpeedToCruise(objMech);
01046 }
01047 }
01048
01049 void StartVTOLCrash(MECH * objMech)
01050 {
01051 if(!Fallen(objMech)) {
01052 MechSpeed(objMech) = 0.0;
01053 MechDesiredSpeed(objMech) = 0.0;
01054 SetMaxSpeed(objMech, 0.0);
01055
01056 if(!Landed(objMech)) {
01057 mech_notify(objMech, MECHALL,
01058 "You ponder F = ma, S = F/m, S = at^2 => S=agt^2 in relation to the ground.");
01059 MechVerticalSpeed(objMech) = 0;
01060 mech_notify(objMech, MECHALL,
01061 "You start free-fall.. Enjoy the ride!");
01062 MechLOSBroadcast(objMech, "starts to fall to the ground!");
01063 MECHEVENT(objMech, EVENT_FALL, mech_fall_event, FALL_TICK, -1);
01064
01065
01066
01067
01068
01069
01070
01071 }
01072 }
01073 }
01074
01075 void HandleAdvFasaVehicleCrit(MECH * wounded, MECH * attacker, int LOS,
01076 int hitloc, int num)
01077 {
01078 int wRoll = Roll();
01079
01080 if(MechMove(wounded) == MOVE_NONE)
01081 return;
01082
01083 if(wRoll < 6)
01084 return;
01085
01086 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01087
01088 switch (MechType(wounded)) {
01089 case CLASS_VEH_GROUND:
01090 switch (hitloc) {
01091 case FSIDE:
01092 switch (wRoll) {
01093 case 6:
01094 DoVehicleDriverCrit(wounded);
01095 break;
01096
01097 case 7:
01098 DoWeaponJamCrit(wounded, hitloc);
01099 break;
01100
01101 case 8:
01102 DoVehicleStablizerCrit(wounded, hitloc);
01103 break;
01104
01105 case 9:
01106 DoVehicleSensorCrit(wounded);
01107 break;
01108
01109 case 10:
01110 DoVehicleCommanderHit(wounded);
01111 break;
01112
01113 case 11:
01114 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01115 break;
01116
01117 case 12:
01118 DoVehicleCrewKilledCrit(wounded, attacker);
01119 break;
01120 }
01121 break;
01122
01123 case LSIDE:
01124 case RSIDE:
01125 switch (wRoll) {
01126 case 6:
01127 DoCargoInfantryCrit(wounded, hitloc);
01128 break;
01129
01130 case 7:
01131 DoWeaponJamCrit(wounded, hitloc);
01132 break;
01133
01134 case 8:
01135 DoVehicleCrewStunnedCrit(wounded);
01136 break;
01137
01138 case 9:
01139 DoVehicleStablizerCrit(wounded, hitloc);
01140 break;
01141
01142 case 10:
01143 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01144 break;
01145
01146 case 11:
01147 DoVehicleEngineHit(wounded, attacker);
01148 break;
01149
01150 case 12:
01151 DoVehicleFuelTankCrit(wounded, attacker);
01152 break;
01153 }
01154 break;
01155
01156 case BSIDE:
01157 switch (wRoll) {
01158 case 6:
01159 DoWeaponJamCrit(wounded, hitloc);
01160 break;
01161
01162 case 7:
01163 DoCargoInfantryCrit(wounded, hitloc);
01164 break;
01165
01166 case 8:
01167 DoVehicleStablizerCrit(wounded, hitloc);
01168 break;
01169
01170 case 9:
01171 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01172 break;
01173
01174 case 10:
01175 DoVehicleEngineHit(wounded, attacker);
01176 break;
01177
01178 case 11:
01179 DoAmmunitionCrit(wounded, attacker, hitloc, LOS);
01180 break;
01181
01182 case 12:
01183 DoVehicleFuelTankCrit(wounded, attacker);
01184 break;
01185 }
01186 break;
01187
01188 case TURRET:
01189 switch (wRoll) {
01190 case 6:
01191 DoVehicleStablizerCrit(wounded, hitloc);
01192 break;
01193
01194 case 7:
01195 DoTurretJamCrit(wounded);
01196 break;
01197
01198 case 8:
01199 DoWeaponJamCrit(wounded, hitloc);
01200 break;
01201
01202 case 9:
01203 DoTurretLockCrit(wounded);
01204 break;
01205
01206 case 10:
01207 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01208 break;
01209
01210 case 11:
01211 DoTurretBlownOffCrit(wounded, attacker, LOS);
01212 break;
01213
01214 case 12:
01215 DoAmmunitionCrit(wounded, attacker, hitloc, LOS);
01216 break;
01217 }
01218 break;
01219 }
01220 break;
01221
01222 case CLASS_VTOL:
01223 switch (hitloc) {
01224 case FSIDE:
01225 switch (wRoll) {
01226 case 6:
01227 DoVTOLCoPilotCrit(wounded);
01228 break;
01229
01230 case 7:
01231 DoWeaponJamCrit(wounded, hitloc);
01232 break;
01233
01234 case 8:
01235 DoVehicleStablizerCrit(wounded, hitloc);
01236 break;
01237
01238 case 9:
01239 DoVehicleSensorCrit(wounded);
01240 break;
01241
01242 case 10:
01243 DoVTOLPilotHit(wounded);
01244 break;
01245
01246 case 11:
01247 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01248 break;
01249
01250 case 12:
01251 DoVehicleCrewKilledCrit(wounded, attacker);
01252 break;
01253 }
01254 break;
01255
01256 case LSIDE:
01257 case RSIDE:
01258 switch (wRoll) {
01259 case 6:
01260 DoWeaponJamCrit(wounded, hitloc);
01261 break;
01262
01263 case 7:
01264 DoCargoInfantryCrit(wounded, hitloc);
01265 break;
01266
01267 case 8:
01268 DoVehicleStablizerCrit(wounded, hitloc);
01269 break;
01270
01271 case 9:
01272 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01273 break;
01274
01275 case 10:
01276 DoVehicleEngineHit(wounded, attacker);
01277 break;
01278
01279 case 11:
01280 DoAmmunitionCrit(wounded, attacker, hitloc, LOS);
01281 break;
01282
01283 case 12:
01284 DoVehicleFuelTankCrit(wounded, attacker);
01285 break;
01286 }
01287 break;
01288
01289 case BSIDE:
01290 switch (wRoll) {
01291 case 6:
01292 DoCargoInfantryCrit(wounded, hitloc);
01293 break;
01294
01295 case 7:
01296 DoWeaponJamCrit(wounded, hitloc);
01297 break;
01298
01299 case 8:
01300 DoVehicleStablizerCrit(wounded, hitloc);
01301 break;
01302
01303 case 9:
01304 DoWeaponDestroyedCrit(attacker, wounded, hitloc, LOS);
01305 break;
01306
01307 case 10:
01308 DoVehicleSensorCrit(wounded);
01309 break;
01310
01311 case 11:
01312 DoVehicleEngineHit(wounded, attacker);
01313 break;
01314
01315 case 12:
01316 DoVehicleFuelTankCrit(wounded, attacker);
01317 break;
01318 }
01319 break;
01320
01321 case ROTOR:
01322 switch (wRoll) {
01323 case 6:
01324 case 7:
01325 case 8:
01326 DoVTOLRotorDamagedCrit(wounded);
01327 break;
01328
01329 case 9:
01330 case 10:
01331 DoVTOLTailRotorDamagedCrit(wounded);
01332 break;
01333
01334 case 11:
01335 case 12:
01336 DoVTOLRotorDestroyedCrit(wounded, attacker, LOS);
01337 break;
01338 }
01339 break;
01340 }
01341 break;
01342 }
01343
01344 }
01345
01346 void HandleVTOLCrit(MECH * wounded, MECH * attacker, int LOS, int hitloc,
01347 int num)
01348 {
01349 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01350 switch (random() % 6) {
01351 case 0:
01352
01353 mech_notify(wounded, MECHALL, "Your cockpit is destroyed!");
01354 if(!Landed(wounded)) {
01355 mech_notify(attacker, MECHALL,
01356 "You knock the VTOL out of the sky!");
01357 MechLOSBroadcast(wounded, "falls down from the sky!");
01358 MechFalls(wounded, MechsElevation(wounded), 0);
01359 }
01360 if(!Destroyed(wounded)) {
01361 DestroyMech(wounded, attacker, 1);
01362 }
01363 KillMechContentsIfIC(wounded->mynum);
01364 break;
01365 case 1:
01366
01367
01368 JamMainWeapon(wounded);
01369 break;
01370 case 2:
01371
01372 mech_notify(wounded, MECHALL, "Your engine takes a direct hit!");
01373 if(!Landed(wounded)) {
01374 if(MechRTerrain(wounded) == GRASSLAND ||
01375 MechRTerrain(wounded) == ROAD ||
01376 MechRTerrain(wounded) == BUILDING) {
01377 if(MadePilotSkillRoll(wounded,
01378 MechZ(wounded) -
01379 MechElevation(wounded))) {
01380 mech_notify(wounded, MECHALL, "You land safely!");
01381 MechStatus(wounded) |= LANDED;
01382 MechZ(wounded) = MechElevation(wounded);
01383 MechFZ(wounded) = ZSCALE * MechZ(wounded);
01384 SetMaxSpeed(wounded, 0.0);
01385 MechVerticalSpeed(wounded) = 0.0;
01386 }
01387 } else {
01388 mech_notify(wounded, MECHALL, "The ground rushes up to meet you!");
01389 mech_notify(attacker, MECHALL,
01390 "You knock the VTOL out of the sky!");
01391 MechLOSBroadcast(wounded, "falls from the sky!");
01392 MechFalls(wounded, MechsElevation(wounded), 0);
01393 }
01394 }
01395 SetMaxSpeed(wounded, 0.0);
01396 break;
01397 case 3:
01398
01399 mech_notify(wounded, MECHALL, "Your cockpit is destroyed!");
01400 if(!(MechStatus(wounded) & LANDED)) {
01401 mech_notify(attacker, MECHALL,
01402 "You knock the VTOL out of the sky!");
01403 MechLOSBroadcast(wounded, "falls from the sky!");
01404 MechFalls(wounded, MechsElevation(wounded), 0);
01405 }
01406 if(!Destroyed(wounded)) {
01407 DestroyMech(wounded, attacker, 1);
01408 }
01409 KillMechContentsIfIC(wounded->mynum);
01410 break;
01411 case 4:
01412
01413 mech_notify(wounded, MECHALL,
01414 "Your fuel tank explodes in a ball of fire!");
01415 if(wounded != attacker)
01416 MechLOSBroadcast(wounded, "explodes in a ball of fire!");
01417 MechZ(wounded) = MechElevation(wounded);
01418 MechFZ(wounded) = ZSCALE * MechZ(wounded);
01419 MechSpeed(wounded) = 0.0;
01420 MechVerticalSpeed(wounded) = 0.0;
01421 DestroyMech(wounded, attacker, 0);
01422 explode_unit(wounded, attacker);
01423 break;
01424 case 5:
01425
01426 mech_notify(wounded, MECHALL, "Your power plant explodes!");
01427 MechLOSBroadcast(wounded, "suddenly explodes!");
01428 MechZ(wounded) = MechElevation(wounded);
01429 MechFZ(wounded) = ZSCALE * MechZ(wounded);
01430 MechSpeed(wounded) = 0.0;
01431 MechVerticalSpeed(wounded) = 0.0;
01432 DestroyMech(wounded, attacker, 0);
01433 if(!(MechSections(wounded)[BSIDE].config & CASE_TECH))
01434 explode_unit(wounded, attacker);
01435 else
01436 DestroySection(wounded, attacker, LOS, BSIDE);
01437 }
01438 }
01439
01440 void DestroyMainWeapon(MECH * mech)
01441 {
01442 unsigned char weaparray[MAX_WEAPS_SECTION];
01443 unsigned char weapdata[MAX_WEAPS_SECTION];
01444 int critical[MAX_WEAPS_SECTION];
01445 int count;
01446 int loop;
01447 int ii;
01448 int tempcrit;
01449 int maxcrit = 0;
01450 int maxloc = 0;
01451 int critfound = 0;
01452 unsigned char maxtype = 0;
01453 int firstCrit = 0;
01454
01455 for(loop = 0; loop < NUM_SECTIONS; loop++) {
01456 if(SectIsDestroyed(mech, loop))
01457 continue;
01458 count = FindWeapons(mech, loop, weaparray, weapdata, critical);
01459 if(count > 0) {
01460 for(ii = 0; ii < count; ii++) {
01461 if(!PartIsBroken(mech, loop, critical[ii])) {
01462
01463 tempcrit = rand();
01464 if(tempcrit > maxcrit) {
01465 critfound = 1;
01466 maxcrit = tempcrit;
01467 maxloc = loop;
01468 maxtype = weaparray[ii];
01469 }
01470 }
01471 }
01472 }
01473 }
01474 if(critfound) {
01475 firstCrit = FindFirstWeaponCrit(mech, maxloc, -1, 0,
01476 I2Weapon(maxtype), 1);
01477 DestroyWeapon(mech, maxloc, I2Weapon(maxtype), 1, firstCrit,
01478 GetWeaponCrits(mech, maxtype));
01479 mech_printf(mech, MECHALL,
01480 "%%ch%%crYour %s is destroyed!%%c",
01481 &MechWeapons[maxtype].name[3]);
01482 }
01483 }
01484
01485 void HandleFasaVehicleCrit(MECH * wounded, MECH * attacker, int LOS,
01486 int hitloc, int num)
01487 {
01488 if(MechMove(wounded) == MOVE_NONE)
01489 return;
01490
01491 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01492 switch (random() % 6) {
01493 case 0:
01494
01495 headhitmwdamage(wounded, attacker, 1);
01496 break;
01497 case 1:
01498
01499
01500 JamMainWeapon(wounded);
01501 break;
01502 case 2:
01503
01504 mech_notify(wounded, MECHALL,
01505 "Your engine takes a direct hit! You can't move anymore.");
01506 SetMaxSpeed(wounded, 0.0);
01507 break;
01508 case 3:
01509
01510 mech_notify(wounded, MECHALL,
01511 "Your armor is pierced and you are killed instantly!");
01512 DestroyMech(wounded, attacker, 0);
01513 KillMechContentsIfIC(wounded->mynum);
01514 break;
01515 case 4:
01516
01517 mech_notify(wounded, MECHALL,
01518 "Your fuel tank explodes in a ball of fire!");
01519 if(wounded != attacker)
01520 MechLOSBroadcast(wounded, "explodes in a ball of fire!");
01521 DestroyMech(wounded, attacker, 0);
01522 explode_unit(wounded, attacker);
01523 break;
01524 case 5:
01525
01526 mech_notify(wounded, MECHALL, "Your power plant explodes!");
01527 if(wounded != attacker)
01528 MechLOSBroadcast(wounded, "suddenly explodes!");
01529 DestroyMech(wounded, attacker, 0);
01530 if(!(MechSections(wounded)[BSIDE].config & CASE_TECH))
01531 explode_unit(wounded, attacker);
01532 else
01533 DestroySection(wounded, attacker, LOS, BSIDE);
01534 break;
01535 }
01536 }
01537
01538 void HandleVehicleCrit(MECH * wounded, MECH * attacker, int LOS,
01539 int hitloc, int num)
01540 {
01541 if(MechMove(wounded) == MOVE_NONE)
01542 return;
01543 if(hitloc == TURRET) {
01544 if(Number(1, 3) == 2) {
01545 if(!(MechTankCritStatus(wounded) & TURRET_LOCKED)) {
01546 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01547 MechTankCritStatus(wounded) |= TURRET_LOCKED;
01548 mech_notify(wounded, MECHALL,
01549 "Your turret takes a direct hit and locks up!");
01550 }
01551 return;
01552 }
01553 } else
01554 switch (Number(1, 10)) {
01555 case 1:
01556 case 2:
01557 case 3:
01558 case 4:
01559 if(!Fallen(wounded)) {
01560 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01561 switch (MechMove(wounded)) {
01562 case MOVE_TRACK:
01563 mech_notify(wounded, MECHALL,
01564 "One of your tracks is damaged!");
01565 break;
01566 case MOVE_WHEEL:
01567 mech_notify(wounded, MECHALL,
01568 "One of your wheels is damaged!");
01569 break;
01570 case MOVE_HOVER:
01571 mech_notify(wounded, MECHALL,
01572 "Your air skirt is damaged!");
01573 break;
01574 case MOVE_HULL:
01575 case MOVE_SUB:
01576 case MOVE_FOIL:
01577 mech_notify(wounded, MECHALL, "Your craft suddenly slows!");
01578 break;
01579 }
01580 LowerMaxSpeed(wounded, MP1);
01581 }
01582 return;
01583 break;
01584 case 5:
01585 if(!Fallen(wounded)) {
01586 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01587 switch (MechMove(wounded)) {
01588 case MOVE_TRACK:
01589 mech_notify(wounded, MECHALL,
01590 "One of your tracks is destroyed, immobilizing your vehicle!");
01591 break;
01592 case MOVE_WHEEL:
01593 mech_notify(wounded, MECHALL,
01594 "One of your wheels is destroyed, immobilizing your vehicle!");
01595 break;
01596 case MOVE_HOVER:
01597 mech_notify(wounded, MECHALL,
01598 "Your lift fan is destroyed, immobilizing your vehicle!");
01599 break;
01600 case MOVE_HULL:
01601 case MOVE_SUB:
01602 case MOVE_FOIL:
01603 mech_notify(wounded, MECHALL,
01604 "Your engines cut out and you drift to a halt!");
01605 }
01606 SetMaxSpeed(wounded, 0.0);
01607
01608 MakeMechFall(wounded);
01609 }
01610 return;
01611 break;
01612 }
01613 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!%c");
01614 switch (random() % 6) {
01615 case 0:
01616
01617 headhitmwdamage(wounded, attacker, 1);
01618 break;
01619 case 1:
01620
01621
01622 JamMainWeapon(wounded);
01623 break;
01624 case 2:
01625
01626 mech_notify(wounded, MECHALL,
01627 "Your engine takes a direct hit! You can't move anymore.");
01628 SetMaxSpeed(wounded, 0.0);
01629 break;
01630 case 3:
01631
01632 mech_notify(wounded, MECHALL,
01633 "Your armor is pierced and you are killed instantly!");
01634 DestroyMech(wounded, attacker, 0);
01635 KillMechContentsIfIC(wounded->mynum);
01636 break;
01637 case 4:
01638
01639 mech_notify(wounded, MECHALL,
01640 "Your fuel tank explodes in a ball of fire!");
01641 if(wounded != attacker)
01642 MechLOSBroadcast(wounded, "explodes in a ball of fire!");
01643 DestroyMech(wounded, attacker, 0);
01644 explode_unit(wounded, attacker);
01645 break;
01646 case 5:
01647
01648 mech_notify(wounded, MECHALL, "Your power plant explodes!");
01649 if(wounded != attacker)
01650 MechLOSBroadcast(wounded, "suddenly explodes!");
01651 DestroyMech(wounded, attacker, 0);
01652 explode_unit(wounded, attacker);
01653 break;
01654 }
01655 }
01656
01657 int HandleMechCrit(MECH * wounded, MECH * attacker, int LOS, int hitloc,
01658 int critHit, int critType, int critData)
01659 {
01660 MECH *mech = wounded;
01661 int weapindx, damage, loop, destroycrit, weapon_slot;
01662 int temp;
01663 char locname[30];
01664 char msgbuf[MBUF_SIZE];
01665 int tLocIsArm = ((hitloc == LARM || hitloc == RARM) &&
01666 !MechIsQuad(wounded));
01667 int tLocIsLeg = ((hitloc == LLEG || hitloc == RLEG) || ((hitloc == LARM
01668 || hitloc ==
01669 RARM)
01670 &&
01671 MechIsQuad
01672 (wounded)));
01673 char partBuf[100];
01674
01675 MAP *map = FindObjectsData(wounded->mapindex);
01676
01677 ArmorStringFromIndex(hitloc, locname, MechType(wounded),
01678 MechMove(wounded));
01679 mech_notify(wounded, MECHALL, "%ch%cyCRITICAL HIT!!%c");
01680
01681 if(IsAmmo(critType)) {
01682
01683
01684 weapindx = Ammo2WeaponI(critType);
01685 damage = critData * MechWeapons[weapindx].damage;
01686 if(IsMissile(weapindx) || IsArtillery(weapindx)) {
01687 for(loop = 0; MissileHitTable[loop].key != -1; loop++)
01688 if(MissileHitTable[loop].key == weapindx)
01689 damage *= MissileHitTable[loop].num_missiles[10];
01690 }
01691 if(MechWeapons[weapindx].special & (GAUSS | NOBOOM)) {
01692 if(MechWeapons[weapindx].special & GAUSS)
01693 mech_notify(wounded, MECHALL,
01694 "One of your Gauss Rifle ammo feeds is destroyed");
01695 DestroyPart(wounded, hitloc, critHit);
01696 } else if(damage) {
01697 ammo_explosion(attacker, wounded, hitloc, critHit, damage);
01698 } else {
01699 mech_notify(wounded, MECHALL,
01700 "You have no ammunition left in that location, lucky you!");
01701 DestroyPart(wounded, hitloc, critHit);
01702 }
01703 return 1;
01704 }
01705
01706 if(PartIsBroken(wounded, hitloc, critHit) && IsWeapon(critType) &&
01707 !PartIsDisabled(wounded, hitloc, critHit)) {
01708 while (--critHit && GetPartType(wounded, hitloc, critHit) == critType)
01709 if(PartIsDestroyed(wounded, hitloc, critHit))
01710 break;
01711 mech_printf(wounded, MECHALL,
01712 "Your destroyed %s is damaged some more!",
01713 &MechWeapons[Weapon2I(critType)].name[3]);
01714 DestroyPart(wounded, hitloc, critHit + 1);
01715 return 1;
01716 }
01717
01718 if(PartIsNonfunctional(wounded, hitloc, critHit)) {
01719 if(IsSpecial(critType)) {
01720 switch (Special2I(critType)) {
01721 case LIFE_SUPPORT:
01722 strcpy(partBuf, "life support");
01723 break;
01724 case COCKPIT:
01725 strcpy(partBuf, "cockpit");
01726 break;
01727 case SENSORS:
01728 strcpy(partBuf, "sensors");
01729 break;
01730 case HEAT_SINK:
01731 strcpy(partBuf, "heatsink");
01732 break;
01733 case JUMP_JET:
01734 strcpy(partBuf, "jump jet");
01735 break;
01736 case ENGINE:
01737 strcpy(partBuf, "engine");
01738 break;
01739 case TARGETING_COMPUTER:
01740 strcpy(partBuf, "targeting computer");
01741 break;
01742 case GYRO:
01743 strcpy(partBuf, "gyro");
01744 break;
01745 case SHOULDER_OR_HIP:
01746 if(tLocIsArm)
01747 strcpy(partBuf, "shoulder");
01748 else
01749 strcpy(partBuf, "hip");
01750 break;
01751 case LOWER_ACTUATOR:
01752 case UPPER_ACTUATOR:
01753 case HAND_OR_FOOT_ACTUATOR:
01754 if(tLocIsArm) {
01755 if(Special2I(critType) == HAND_OR_FOOT_ACTUATOR)
01756 strcpy(partBuf, "hand actuator");
01757 else
01758 strcpy(partBuf, "arm actuator");
01759 } else {
01760 if(Special2I(critType) == HAND_OR_FOOT_ACTUATOR)
01761 strcpy(partBuf, "foot actuator");
01762 else
01763 strcpy(partBuf, "arm actuator");
01764 }
01765 break;
01766 case C3_MASTER:
01767 strcpy(partBuf, "C3 system");
01768 break;
01769 case C3_SLAVE:
01770 strcpy(partBuf, "C3 system");
01771 break;
01772 case C3I:
01773 strcpy(partBuf, "C3i system");
01774 break;
01775 case TAG:
01776 strcpy(partBuf, "TAG system");
01777 break;
01778 case ECM:
01779 strcpy(partBuf, "ECM system");
01780 break;
01781 case ANGELECM:
01782 strcpy(partBuf, "Angel ECM system");
01783 break;
01784 case BEAGLE_PROBE:
01785 strcpy(partBuf, "Beagle Active Probe");
01786 break;
01787 case BLOODHOUND_PROBE:
01788 strcpy(partBuf, "Bloodhound Active Probe");
01789 break;
01790 case ARTEMIS_IV:
01791 strcpy(partBuf, "ArtemisIV system");
01792 break;
01793 case AXE:
01794 strcpy(partBuf, "axe");
01795 break;
01796 case SWORD:
01797 strcpy(partBuf, "sword");
01798 break;
01799 case MACE:
01800 strcpy(partBuf, "mace");
01801 break;
01802 case DUAL_SAW:
01803 strcpy(partBuf, "dual saw");
01804 break;
01805 case DS_AERODOOR:
01806 strcpy(partBuf, "aero doors");
01807 break;
01808 case DS_MECHDOOR:
01809 strcpy(partBuf, "mech doors");
01810 break;
01811 case NULL_SIGNATURE_SYSTEM:
01812 strcpy(partBuf, "Null Signature System");
01813 break;
01814 }
01815 }
01816
01817 mech_printf(wounded, MECHALL,
01818 "Part of your non-working %s has been hit!", partBuf);
01819 DestroyPart(wounded, hitloc, critHit);
01820 return 1;
01821 }
01822
01823 if(IsWeapon(critType)) {
01824 if(handleWeaponCrit(attacker, wounded, hitloc, critHit, critType,
01825 LOS)) {
01826 return 1;
01827 }
01828
01829 scoreEnhancedWeaponCriticalHit(mech, attacker, LOS, hitloc, critHit);
01830
01831
01832
01833
01834 return 1;
01835 }
01836
01837 if(IsSpecial(critType)) {
01838 destroycrit = 1;
01839 switch (Special2I(critType)) {
01840 case LIFE_SUPPORT:
01841 MechCritStatus(wounded) |= LIFE_SUPPORT_DESTROYED;
01842 mech_notify(wounded, MECHALL,
01843 "Your life support has been destroyed!");
01844 break;
01845 case COCKPIT:
01846
01847 mech_notify(wounded, MECHALL,
01848 "Your cockpit is destroyed, your blood boils, and your body is fried! %cyYou're dead!%cn");
01849 if(!Destroyed(wounded)) {
01850 Destroy(wounded);
01851 ChannelEmitKill(wounded, attacker);
01852 }
01853
01854 if(LOS && attacker)
01855 mech_notify(attacker, MECHALL,
01856 "You destroy the cockpit! The pilot's blood splatters down the sides!");
01857 MechLOSBroadcast(wounded,
01858 "spasms for a second then remains oddly still.");
01859 MechPilot(wounded) = -1;
01860 KillMechContentsIfIC(wounded->mynum);
01861 break;
01862 case SENSORS:
01863 if(!(MechCritStatus(wounded) & SENSORS_DAMAGED)) {
01864 MechLRSRange(wounded) /= 2;
01865 MechTacRange(wounded) /= 2;
01866 MechScanRange(wounded) /= 2;
01867 MechBTH(wounded) += 2;
01868 MechCritStatus(wounded) |= SENSORS_DAMAGED;
01869 mech_notify(wounded, MECHALL,
01870 "Your sensors have been damaged!");
01871 } else {
01872 MechLRSRange(wounded) = 0;
01873 MechTacRange(wounded) = 0;
01874 MechScanRange(wounded) = 0;
01875 MechBTH(wounded) = 75;
01876 mech_notify(wounded, MECHALL,
01877 "Your sensors have been destroyed!");
01878 }
01879 break;
01880 case HEAT_SINK:
01881 if(MechHasDHS(mech)) {
01882 MechRealNumsinks(wounded) -= 2;
01883 DestroyWeapon(wounded, hitloc, critType, critHit, 1,
01884 HS_Size(mech));
01885 destroycrit = 0;
01886 } else
01887 MechRealNumsinks(wounded)--;
01888 mech_notify(wounded, MECHALL, "You lost a heat sink!");
01889 if(!Destroyed(wounded)) {
01890 sprintf(msgbuf, "'s %s is covered in a green mist!", locname);
01891 MechLOSBroadcast(wounded, msgbuf);
01892 }
01893 break;
01894 case JUMP_JET:
01895 if(!Destroyed(wounded) && Started(wounded)) {
01896 sprintf(msgbuf,
01897 "'s %s flares as superheated plasma spews out!",
01898 locname);
01899 MechLOSBroadcast(wounded, msgbuf);
01900 }
01901 MechJumpSpeed(wounded) -= MP1;
01902 if(MechJumpSpeed(wounded) < 0)
01903 MechJumpSpeed(wounded) = 0;
01904 mech_notify(wounded, MECHALL,
01905 "One of your jump jet engines has shut down!");
01906 if(attacker && MechJumpSpeed(wounded) < MP1 && Jumping(wounded)) {
01907 mech_notify(wounded, MECHALL,
01908 "Losing your last jump jet, you fall from the sky!");
01909 MechLOSBroadcast(wounded, "falls from the sky!");
01910 MechFalls(wounded, 1, 0);
01911 domino_space(wounded, 2);
01912 }
01913 break;
01914 case ENGINE:
01915 if(!Destroyed(wounded) && Started(wounded)) {
01916 sprintf(msgbuf, "'s %s spews black smoke!", locname);
01917 MechLOSBroadcast(wounded, msgbuf);
01918 }
01919 if(MechEngineHeat(wounded) < 10) {
01920 MechEngineHeat(wounded) += 5;
01921 mech_notify(wounded, MECHALL,
01922 "Your engine shielding takes a hit! It's getting hotter in here!");
01923 } else if(MechEngineHeat(wounded) < 15) {
01924 MechEngineHeat(wounded) = 15;
01925 mech_notify(wounded, MECHALL, "Your engine is destroyed!");
01926 if(wounded != attacker &&
01927 !(MechStatus(wounded) & DESTROYED) && attacker)
01928 mech_notify(attacker, MECHALL,
01929 "You destroy the engine!");
01930 DestroyMech(wounded, attacker, 1);
01931 }
01932 break;
01933 case TARGETING_COMPUTER:
01934 if(!MechCritStatus(wounded) & TC_DESTROYED) {
01935 mech_notify(wounded, MECHALL,
01936 "Your targeting computer is destroyed!");
01937 MechCritStatus(wounded) |= TC_DESTROYED;
01938 }
01939 break;
01940 case GYRO:
01941
01942 if(MechSpecials2(wounded) & HDGYRO_TECH)
01943 if(!MechCritStatus2(wounded) & HDGYRO_DAMAGED) {
01944 sprintf(msgbuf, "emits a screech as its "
01945 "hardened gyro buckles slightly!");
01946 MechLOSBroadcast(wounded, msgbuf);
01947 MechCritStatus2(wounded) |= HDGYRO_DAMAGED;
01948 mech_notify(wounded, MECHALL,
01949 "Your hardened gyro takes a hit!");
01950 break;
01951 }
01952
01953 if(!(MechCritStatus(wounded) & GYRO_DAMAGED)) {
01954 if(!Destroyed(wounded) && Started(wounded)) {
01955 sprintf(msgbuf, "emits a loud screech as "
01956 "its gyro buckles under the impact!");
01957 MechLOSBroadcast(wounded, msgbuf);
01958 }
01959 MechCritStatus(wounded) |= GYRO_DAMAGED;
01960 MechPilotSkillBase(wounded) += 3;
01961 mech_notify(wounded, MECHALL, "Your Gyro has been damaged!");
01962 if(attacker)
01963 if(!MadePilotSkillRoll(wounded, 0) && !Fallen(wounded)) {
01964 if(!Jumping(wounded) && !OODing(wounded)) {
01965 mech_notify(wounded, MECHALL,
01966 "You lose your balance and fall down!");
01967 MechLOSBroadcast(wounded,
01968 "stumbles and falls down.");
01969 MechFalls(wounded, 1, 0);
01970 } else {
01971 mech_notify(wounded, MECHALL,
01972 "You fall from the sky!");
01973 MechLOSBroadcast(wounded, "falls from the sky!");
01974 MechFalls(wounded, JumpSpeedMP(wounded, map), 0);
01975 domino_space(wounded, 2);
01976 }
01977 }
01978 } else if(!(MechCritStatus(wounded) & GYRO_DESTROYED)) {
01979 MechCritStatus(wounded) |= GYRO_DESTROYED;
01980 mech_notify(wounded, MECHALL,
01981 "Your Gyro has been destroyed!");
01982
01983 if(attacker) {
01984 if(!Fallen(wounded) && !Jumping(wounded) &&
01985 !OODing(wounded)) {
01986 mech_notify(wounded, MECHALL,
01987 "You fall and you can't get up!");
01988 MechLOSBroadcast(wounded, "is knocked over!");
01989 MechFalls(wounded, 1, 0);
01990 } else if(!Fallen(wounded)
01991 && (Jumping(wounded) || OODing(wounded))) {
01992 mech_notify(wounded, MECHALL,
01993 "You fall from the sky!");
01994 MechLOSBroadcast(wounded, "falls from the sky!");
01995 MechFalls(wounded, JumpSpeedMP(wounded, map), 0);
01996 domino_space(wounded, 2);
01997 }
01998 }
01999 } else {
02000 mech_notify(wounded, MECHALL,
02001 "Your destroyed gyro takes another hit!");
02002 }
02003 break;
02004 case SHOULDER_OR_HIP:
02005 DestroyPart(wounded, hitloc, critHit);
02006 destroycrit = 0;
02007
02008 if(tLocIsArm) {
02009 mech_notify(wounded, MECHALL,
02010 "Your shoulder joint takes a hit and is frozen!");
02011 NormalizeLocActuatorCrits(wounded, hitloc);
02012 } else if(tLocIsLeg) {
02013 if(!Destroyed(wounded) && Started(wounded)) {
02014 sprintf(msgbuf, "'s hip locks into place!");
02015 MechLOSBroadcast(wounded, msgbuf);
02016 }
02017
02018 mech_notify(wounded, MECHALL,
02019 "Your hip takes a direct hit and freezes up!");
02020
02021 if(!(MechCritStatus(wounded) & HIP_DAMAGED)) {
02022 MechCritStatus(wounded) |= HIP_DAMAGED;
02023 } else {
02024 if(!MechIsQuad(wounded))
02025 MechCritStatus(wounded) |= HIP_DESTROYED;
02026 }
02027
02028 NormalizeAllActuatorCrits(wounded);
02029
02030 if(attacker && !Jumping(wounded) && !OODing(wounded)
02031 && !MadePilotSkillRoll(wounded, 0)) {
02032 mech_notify(wounded, MECHALL,
02033 "You lose your balance and fall down!");
02034 MechLOSBroadcast(wounded, "stumbles and falls down!");
02035 MechFalls(wounded, 1, 0);
02036 }
02037 }
02038 break;
02039 case LOWER_ACTUATOR:
02040 case UPPER_ACTUATOR:
02041 case HAND_OR_FOOT_ACTUATOR:
02042 DestroyPart(wounded, hitloc, critHit);
02043 destroycrit = 0;
02044
02045 if(tLocIsArm) {
02046 if(Special2I(critType) == HAND_OR_FOOT_ACTUATOR)
02047 mech_printf(wounded, MECHALL,
02048 "Your %s hand actuator is destroyed!",
02049 hitloc == LARM ? "left" : "right");
02050 else
02051 mech_printf(wounded, MECHALL,
02052 "Your %s %s arm actuator is destroyed!",
02053 hitloc == LARM ? "left" : "right",
02054 Special2I(critType) ==
02055 LOWER_ACTUATOR ? "lower" : "upper");
02056
02057 if((Special2I(critType) == HAND_OR_FOOT_ACTUATOR) &&
02058 (MechSections(mech)[hitloc].specials & CARRYING_CLUB))
02059 DropClub(mech);
02060
02061 NormalizeLocActuatorCrits(wounded, hitloc);
02062 } else if(tLocIsLeg) {
02063 mech_notify(wounded, MECHALL,
02064 "One of your leg actuators is destroyed!");
02065
02066 if(OkayCritSectS(hitloc, 0, SHOULDER_OR_HIP)) {
02067 if(!Destroyed(wounded) && Started(wounded)) {
02068 sprintf(msgbuf, "'s %s twists in an odd way!",
02069 locname);
02070 MechLOSBroadcast(wounded, msgbuf);
02071 }
02072
02073 NormalizeAllActuatorCrits(wounded);
02074
02075 if(attacker && !Jumping(wounded) && !OODing(wounded)
02076 && !MadePilotSkillRoll(wounded, 0)) {
02077 mech_notify(wounded, MECHALL,
02078 "You lose your balance and fall down!");
02079 MechLOSBroadcast(wounded, "stumbles and falls down!");
02080 MechFalls(wounded, 1, 0);
02081 }
02082 }
02083 }
02084 break;
02085 case C3_MASTER:
02086 temp = MechWorkingC3Masters(mech);
02087 MechWorkingC3Masters(mech) = countWorkingC3MastersOnMech(mech);
02088
02089 if(temp == MechWorkingC3Masters(mech))
02090 mech_notify(wounded, MECHALL,
02091 "Your destroyed C3 system takes another hit!");
02092 else {
02093 if(MechWorkingC3Masters(mech) == 0) {
02094 MechCritStatus(wounded) |= C3_DESTROYED;
02095
02096 checkTAG(mech);
02097 }
02098
02099 if(MechTotalC3Masters(mech))
02100 mech_notify(wounded, MECHALL,
02101 "One of your C3 systems has been destroyed!");
02102 else
02103 mech_notify(wounded, MECHALL,
02104 "Your C3 system has been destroyed!");
02105 }
02106
02107 break;
02108 case C3_SLAVE:
02109 MechCritStatus(wounded) |= C3_DESTROYED;
02110 mech_notify(wounded, MECHALL,
02111 "Your C3 system has been destroyed!");
02112 break;
02113 case C3I:
02114 MechCritStatus(wounded) |= C3I_DESTROYED;
02115 mech_notify(wounded, MECHALL,
02116 "Your C3i system has been destroyed!");
02117
02118 clearC3iNetwork(mech, 1);
02119 break;
02120 case TAG:
02121 MechCritStatus(wounded) |= TAG_DESTROYED;
02122 mech_notify(wounded, MECHALL,
02123 "Your TAG system has been destroyed!");
02124
02125 checkTAG(mech);
02126 break;
02127 case ECM:
02128 MechCritStatus(wounded) |= ECM_DESTROYED;
02129 mech_notify(wounded, MECHALL,
02130 "Your ECM system has been destroyed!");
02131 DisableECM(wounded);
02132 DisableECCM(wounded);
02133
02134 if(StealthArmorActive(wounded)) {
02135 mech_notify(wounded, MECHALL,
02136 "Your stealth armor system shuts down!");
02137 DisableStealthArmor(wounded);
02138 }
02139
02140 break;
02141 case ANGELECM:
02142 MechCritStatus(wounded) |= ANGEL_ECM_DESTROYED;
02143 mech_notify(wounded, MECHALL,
02144 "Your Angel ECM system has been destroyed!");
02145 DisableAngelECM(wounded);
02146 DisableAngelECCM(wounded);
02147
02148 break;
02149 case BEAGLE_PROBE:
02150 MechCritStatus(wounded) |= BEAGLE_DESTROYED;
02151 MechSpecials(wounded) &= ~BEAGLE_PROBE_TECH;
02152 mech_notify(wounded, MECHALL,
02153 "Your Beagle Active Probe has been destroyed!");
02154 if(((sensors[(short) MechSensor(wounded)[0]].required_special
02155 == BEAGLE_PROBE_TECH) &&
02156 (sensors[(short) MechSensor(wounded)[0]].specials_set
02157 == 1)) ||
02158 ((sensors[(short) MechSensor(wounded)[1]].required_special
02159 == BEAGLE_PROBE_TECH) &&
02160 (sensors[(short) MechSensor(wounded)[1]].specials_set
02161 == 1))) {
02162
02163 if((sensors[(short)
02164 MechSensor(wounded)[0]].required_special ==
02165 BEAGLE_PROBE_TECH) &&
02166 (sensors[(short) MechSensor(wounded)[0]].specials_set
02167 == 1))
02168 MechSensor(wounded)[0] = 0;
02169
02170 if((sensors[(short)
02171 MechSensor(wounded)[1]].required_special ==
02172 BEAGLE_PROBE_TECH) &&
02173 (sensors[(short) MechSensor(wounded)[1]].specials_set
02174 == 1))
02175 MechSensor(wounded)[1] = 0;
02176
02177 MarkForLOSUpdate(wounded);
02178 }
02179 break;
02180 case BLOODHOUND_PROBE:
02181 MechCritStatus(wounded) |= BLOODHOUND_DESTROYED;
02182 MechSpecials2(wounded) &= ~BLOODHOUND_PROBE_TECH;
02183 mech_notify(wounded, MECHALL,
02184 "Your Bloodhound Probe has been destroyed!");
02185
02186 if(((sensors[(short) MechSensor(wounded)[0]].required_special
02187 == BLOODHOUND_PROBE_TECH) &&
02188 (sensors[(short) MechSensor(wounded)[0]].specials_set
02189 == 1)) ||
02190 ((sensors[(short) MechSensor(wounded)[1]].required_special
02191 == BLOODHOUND_PROBE_TECH) &&
02192 (sensors[(short) MechSensor(wounded)[1]].specials_set
02193 == 1))) {
02194
02195 if((sensors[(short)
02196 MechSensor(wounded)[0]].required_special ==
02197 BLOODHOUND_PROBE_TECH) &&
02198 (sensors[(short) MechSensor(wounded)[0]].specials_set
02199 == 1))
02200 MechSensor(wounded)[0] = 0;
02201
02202 if((sensors[(short)
02203 MechSensor(wounded)[1]].required_special ==
02204 BLOODHOUND_PROBE_TECH) &&
02205 (sensors[(short) MechSensor(wounded)[1]].specials_set
02206 == 1))
02207 MechSensor(wounded)[1] = 0;
02208
02209 MarkForLOSUpdate(wounded);
02210 }
02211 break;
02212 case ARTEMIS_IV:
02213 weapon_slot = GetPartData(wounded, hitloc, critHit);
02214 if(weapon_slot > NUM_CRITICALS) {
02215 SendError(tprintf("Artemis IV error on mech %d",
02216 wounded->mynum));
02217 break;
02218 }
02219 GetPartAmmoMode(wounded, hitloc, weapon_slot) &= ~ARTEMIS_MODE;
02220 mech_notify(wounded, MECHALL,
02221 "Your Artemis IV system has been destroyed!");
02222 break;
02223 case AXE:
02224 mech_notify(wounded, MECHALL, "Your axe has been destroyed!");
02225 break;
02226 case SWORD:
02227 mech_notify(wounded, MECHALL, "Your sword has been destroyed!");
02228 break;
02229 case DUAL_SAW:
02230 mech_notify(wounded, MECHALL,
02231 "Your dual saw has been destroyed!");
02232 break;
02233 case MACE:
02234 mech_notify(wounded, MECHALL, "Your mace has been destroyed!");
02235 break;
02236 case DS_AERODOOR:
02237 mech_notify(wounded, MECHALL,
02238 "One of the aero doors has been rendered useless!");
02239 break;
02240 case DS_MECHDOOR:
02241 mech_notify(wounded, MECHALL,
02242 "One of the 'mech doors has been rendered useless!");
02243 case NULL_SIGNATURE_SYSTEM:
02244 mech_notify(wounded, MECHALL,
02245 "Your Null Signature System has been destroyed!");
02246
02247 if(NullSigSysActive(wounded)) {
02248 mech_notify(wounded, MECHALL,
02249 "Your Null Signature System shuts down!");
02250 DisableNullSigSys(wounded);
02251 }
02252
02253 DestroyNullSigSys(wounded);
02254
02255 break;
02256 }
02257
02258 if(destroycrit)
02259 DestroyPart(wounded, hitloc, critHit);
02260 }
02261
02262 return 1;
02263 }
02264
02265 void HandleCritical(MECH * wounded, MECH * attacker, int LOS, int hitloc,
02266 int num)
02267 {
02268 int i;
02269 int critHit;
02270 int critType, critData;
02271 int count, index;
02272 int critList[NUM_CRITICALS];
02273
02274 if(MechStatus(wounded) & COMBAT_SAFE)
02275 return;
02276 if(MechSpecials(wounded) & CRITPROOF_TECH)
02277 return;
02278 if(MechType(wounded) == CLASS_MW && Number(1, 2) == 1)
02279 return;
02280 if(MechType(wounded) != CLASS_MECH && !mudconf.btech_vcrit)
02281 return;
02282 if(MechType(wounded) == CLASS_VEH_GROUND ||
02283 MechType(wounded) == CLASS_VEH_NAVAL) {
02284 if(mudconf.btech_fasaadvvhlcrit) {
02285 for(i = 0; i < num; i++)
02286 HandleAdvFasaVehicleCrit(wounded, attacker, LOS, hitloc, num);
02287
02288 return;
02289 } else if(!mudconf.btech_fasacrit) {
02290 for(i = 0; i < num; i++)
02291 HandleVehicleCrit(wounded, attacker, LOS, hitloc, num);
02292 return;
02293 } else if(mudconf.btech_fasacrit) {
02294 for(i = 0; i < num; i++)
02295 HandleFasaVehicleCrit(wounded, attacker, LOS, hitloc, num);
02296 return;
02297 }
02298 }
02299 if(IsDS(wounded))
02300 return;
02301 if(MechType(wounded) == CLASS_VTOL) {
02302 if(mudconf.btech_fasaadvvtolcrit) {
02303 for(i = 0; i < num; i++)
02304 HandleAdvFasaVehicleCrit(wounded, attacker, LOS, hitloc, num);
02305
02306 return;
02307 } else {
02308 for(i = 0; i < num; i++)
02309 HandleVTOLCrit(wounded, attacker, LOS, hitloc, num);
02310
02311 return;
02312 }
02313 }
02314 while (num > 0) {
02315 count = 0;
02316 while (count == 0) {
02317 for(i = 0; i < NUM_CRITICALS; i++) {
02318 critType = GetPartType(wounded, hitloc, i);
02319 if(!PartIsDestroyed(wounded, hitloc, i)
02320 && !PartIsDamaged(wounded, hitloc, i)
02321 && critType != EMPTY && critType != Special(CASE)
02322 && critType != Special(FERRO_FIBROUS)
02323 && critType != Special(STEALTH_ARMOR)
02324 && critType != Special(HVY_FERRO_FIBROUS)
02325 && critType != Special(LT_FERRO_FIBROUS)
02326 && critType != Special(ENDO_STEEL)
02327 && critType != Special(TRIPLE_STRENGTH_MYOMER)
02328 && critType != Special(SUPERCHARGER)
02329 && critType != Special(MASC)) {
02330 critList[count] = i;
02331 count++;
02332 }
02333 }
02334
02335 if(!count)
02336 return;
02337 }
02338
02339 index = random() % count;
02340 critHit = critList[index];
02341
02342 critType = GetPartType(wounded, hitloc, critHit);
02343 critData = GetPartData(wounded, hitloc, critHit);
02344
02345 if(HandleMechCrit(wounded, attacker, LOS, hitloc, critHit,
02346 critType, critData))
02347 num--;
02348 }
02349 }