00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <math.h>
00017
00018 #include "mech.h"
00019 #include "mech.events.h"
00020 #include "p.mech.bth.h"
00021 #include "p.mech.c3.misc.h"
00022 #include "p.mech.combat.h"
00023 #include "p.mech.enhanced.criticals.h"
00024 #include "p.mech.hitloc.h"
00025 #include "p.mech.los.h"
00026 #include "p.mech.update.h"
00027 #include "p.mech.utils.h"
00028
00029 #ifndef BTH_DEBUG
00030 #define BTHBASE(m,t,n) baseToHit = n;
00031 #define BTHADD(desc,n) baseToHit += n;
00032 #define BTHEND(m)
00033 #else
00034 #define BTHBASE(m,t,n) do { if (t) sprintf(buf, "#%d -> #%d: Base %d", m->mynum, t->mynum, n); else sprintf(buf, "#%d -> (hex): Base %d", m->mynum, n); baseToHit = n; } while (0)
00035 #define BTHADD(desc,n) do { i = n ; if (i) { sprintf(buf+strlen(buf), ", %s: %s%d", desc, i>0 ? "+" : "", i); baseToHit += i; } } while (0)
00036 #define BTHEND(m) SendBTHDebug(tprintf("%s.", buf))
00037 #endif
00038
00039 int arc_override;
00040
00041 int FindNormalBTH(MECH * mech,
00042 MAP * mech_map,
00043 int section,
00044 int critical,
00045 int weapindx, float range, MECH * target, int indirectFire,
00046 dbref * c3Ref)
00047 {
00048 MECH *spotter = NULL;
00049 int baseToHit;
00050 int wFireMode = GetPartFireMode(mech, section, critical);
00051 int wAmmoMode = GetPartAmmoMode(mech, section, critical);
00052 int tInWater = 0;
00053 int tTargetInWater = 0;
00054 int wTargMoveMod = 0;
00055 int rangecheck = 0;
00056 #ifdef BTH_DEBUG
00057 char buf[LBUF_SIZE];
00058 int i;
00059 #endif
00060 int j, rbth = 0;
00061 float enemyX, enemyY, enemyZ;
00062 int wRangeBracket = RANGE_TOFAR;
00063
00064 *c3Ref = -1;
00065
00066 if(target) {
00067 tInWater = ((MechRTerrain(mech) == WATER) && (MechZ(mech) < 0));
00068 tTargetInWater = ((MechRTerrain(target) == WATER) &&
00069 (MechZ(target) < 0));
00070 }
00071
00072 BTHBASE(mech, target, FindPilotGunnery(mech, weapindx));
00073
00074 if(indirectFire < 1000) {
00075 spotter = getMech(MechSpotter(mech));
00076
00077 if(!spotter) {
00078 mech_notify(mech, MECHALL,
00079 "Error finding your spotter! (notify a wiz)");
00080 return 0;
00081 }
00082
00083 BTHADD("Spotting", FindPilotSpotting(spotter) - 4);
00084 }
00085
00086
00087 if(is_aero(mech) && target && !is_aero(target) && !Landed(mech)) {
00088 BTHADD("Aero strafing", 2);
00089 };
00090
00091
00092 if(target && MechType(target) == CLASS_MW)
00093 BTHADD("MechWarrior", 2);
00094
00095
00096 BTHADD("MechBTHMod", MechBTH(mech));
00097
00098
00099 BTHADD("MechLocBTHMod", MechSections(mech)[section].basetohit);
00100
00101
00102 if(tInWater)
00103 BTHADD("InWater", 1);
00104
00105
00106 rangecheck = EGunRange(weapindx);
00107 if(wAmmoMode & STINGER_MODE)
00108 rangecheck += 7;
00109 if(rangecheck < range) {
00110 BTHADD("OutOfRange", 1000);
00111 } else {
00112 if((MechWeapons[weapindx].min >= range) &&
00113 (MechWeapons[weapindx].min > 0)) {
00114 if(!HotLoading(weapindx, GetPartFireMode(mech, section,
00115 critical))) {
00116
00117 rbth = (MechWeapons[weapindx].min - range + 1);
00118 } else {
00119 if(mudconf.btech_hotloadaddshalfbthmod) {
00120 rbth = ((MechWeapons[weapindx].min - range + 2) / 2);
00121 }
00122 }
00123
00124 BTHADD("MinRange", rbth);
00125 } else if(HasC3(mech) && !C3Destroyed(mech) &&
00126 !AnyECMDisturbed(mech) && (MechC3NetworkSize(mech) > 0)) {
00127 wRangeBracket = FindBTHByC3Range(mech, target,
00128 section, weapindx, range,
00129 findC3Range(mech, target, range,
00130 c3Ref, 1), wAmmoMode,
00131 &rbth);
00132
00133 BTHADD("C3Range", rbth);
00134 } else if(HasC3i(mech) && !C3iDestroyed(mech) &&
00135 !AnyECMDisturbed(mech) && (MechC3iNetworkSize(mech) > 0)) {
00136 wRangeBracket = FindBTHByC3Range(mech, target,
00137 section, weapindx, range,
00138 findC3Range(mech, target, range,
00139 c3Ref, 0), wAmmoMode,
00140 &rbth);
00141
00142 BTHADD("C3iRange", rbth);
00143 } else {
00144 wRangeBracket = FindBTHByRange(mech, target, section,
00145 weapindx, range, wFireMode,
00146 wAmmoMode, &rbth);
00147 BTHADD("Range", rbth);
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 if(MechTargComp(mech) == TARGCOMP_SHORT
00160 || MechTargComp(mech) == TARGCOMP_LONG) {
00161 int tmp_range;
00162
00163 if(MechWeapons[weapindx].special & PCOMBAT)
00164 tmp_range = (int) (range * 10 + 0.95);
00165 else
00166 tmp_range = (int) (range + 0.95);
00167
00168 if(tmp_range >
00169 (SectionUnderwater(mech, section) ? MechWeapons[weapindx].
00170 medrange_water : MechWeapons[weapindx].medrange))
00171 BTHADD("TargComp/Long",
00172 MechTargComp(mech) == TARGCOMP_LONG ? -1 : 1);
00173 else if(tmp_range <=
00174 (SectionUnderwater(mech, section) ? MechWeapons[weapindx].
00175 medrange_water : MechWeapons[weapindx].medrange))
00176 BTHADD("TargComp/Short",
00177 MechTargComp(mech) == TARGCOMP_SHORT ? -1 : 1);
00178 }
00179
00180 if(target && MechInfantrySpecials(target) & STEALTH_TECH) {
00181 if(MechInfantrySpecials(target) & FWL_ACHILEUS_STEALTH_TECH) {
00182 if(wRangeBracket == RANGE_SHORT)
00183 BTHADD("FWLStealthBonus", 1);
00184 else if(wRangeBracket == RANGE_MED)
00185 BTHADD("FWLStealthBonus", 2);
00186 else if(wRangeBracket == RANGE_LONG)
00187 BTHADD("FWLStealthBonus", 3);
00188 } else if(MechInfantrySpecials(target) & DC_KAGE_STEALTH_TECH) {
00189 if(wRangeBracket == RANGE_MED)
00190 BTHADD("DCStealthBonus", 1);
00191 else if(wRangeBracket == RANGE_LONG)
00192 BTHADD("DCStealthBonus", 2);
00193 } else if(MechInfantrySpecials(target) & FC_INFILTRATOR_STEALTH_TECH) {
00194 if(wRangeBracket == RANGE_MED)
00195 BTHADD("FCStealthBonus", 1);
00196 else if(wRangeBracket == RANGE_LONG)
00197 BTHADD("FCStealthBonus", 2);
00198 } else if(MechInfantrySpecials(target) &
00199 FC_INFILTRATORII_STEALTH_TECH) {
00200 if(wRangeBracket == RANGE_SHORT)
00201 BTHADD("FCStealthIIBonus", 1);
00202 if(wRangeBracket == RANGE_MED)
00203 BTHADD("FCStealthIIBonus", 1);
00204 else if(wRangeBracket == RANGE_LONG)
00205 BTHADD("FCStealthIIBonus", 2);
00206 }
00207 }
00208
00209
00210 if(MechSections(mech)[section].config & STABILIZERS_DESTROYED)
00211 BTHADD("AttackMoveX2", AttackMovementMods(mech) * 2);
00212 else
00213 BTHADD("AttackMove", AttackMovementMods(mech));
00214
00215
00216 BTHADD("Overheat", OverheatMods(mech));
00217
00218
00219 if(wAmmoMode & AC_AP_MODE)
00220 BTHADD("ArmorPiercing", 1);
00221
00222 if(checkAllSections(mech, INARC_HAYWIRE_ATTACHED))
00223 BTHADD("HaywirePod", 1);
00224
00225 if(target && (wAmmoMode & NARC_MODE) &&
00226 (!(MechWeapons[weapindx].special & NARC)) &&
00227 checkAllSections(target, INARC_HOMING_ATTACHED))
00228 BTHADD("iNARC", -1);
00229
00230 if(MechWeapons[weapindx].special & PULSE)
00231 BTHADD("Pulse", -2);
00232
00233 if(MechWeapons[weapindx].special & MRM)
00234 BTHADD("MRM", 1);
00235
00236 if(MechWeapons[weapindx].special & HVYW)
00237 BTHADD("HeavyWeapon", 1);
00238 if(target && (wAmmoMode & STINGER_MODE)) {
00239 if(FlyingT(target) && !Landed(target))
00240 BTHADD("Stinger (Flying)", -3);
00241 else if(OODing(target))
00242 BTHADD("Stinger (OOD)", -1);
00243 else if(Jumping(target))
00244 BTHADD("Stinger (Jumping)", 0);
00245 }
00246
00247 if(MechWeapons[weapindx].special & ROCKET)
00248 BTHADD("Rocket Launcher", 1);
00249
00250 if(target && (MechType(target) == CLASS_VTOL) &&
00251 (fabs(MechSpeed(target)) > 0.0 ||
00252 fabs(MechVerticalSpeed(target)) > 0.0))
00253 BTHADD("TargetVTOL", 1);
00254
00255 if(target && MechTargComp(mech) == TARGCOMP_AA) {
00256 if(!Landed(target)
00257 && (FlyingT(target) || Jumping(target) || OODing(target)))
00258 BTHADD("TargComp/AA-Fly", MechSpecials(mech) & AA_TECH ? -3 : -2);
00259 else
00260 BTHADD("TargComp/AA-Ground", 1);
00261 }
00262
00263
00264 if(wAmmoMode & LBX_MODE)
00265 BTHADD("LBX", (target && (MechType(target) == CLASS_VTOL) ? -3 : -1));
00266
00267
00268 if(!arc_override && (!spotter && target &&
00269 ((MechTarget(mech) != target->mynum) ||
00270 (Locking(mech)
00271 && MechTargComp(mech) != TARGCOMP_MULTI)))) {
00272 if(FindTargetXY(mech, &enemyX, &enemyY, &enemyZ)) {
00273 if(InWeaponArc(mech, enemyX, enemyY) & (FORWARDARC | TURRETARC))
00274 BTHADD("UnstableLock/Fwarc", 1);
00275 else
00276 BTHADD("UnstableLock", 2);
00277 } else {
00278 BTHADD("HipShot-NoLock", 2);
00279 }
00280 }
00281
00282 if(MechTargComp(mech) == TARGCOMP_MULTI) {
00283 if(FindTargetXY(mech, &enemyX, &enemyY, &enemyZ)) {
00284 if(!(InWeaponArc(mech, enemyX, enemyY) & FORWARDARC))
00285 BTHADD("TargComp/MultiSideArc", 1);
00286 }
00287 }
00288
00289
00290 if(!target &&
00291 (MechStatus(mech) & (LOCK_HEX | LOCK_BUILDING | LOCK_HEX_IGN |
00292 LOCK_HEX_CLR)))
00293 BTHADD("HexBonus", -4);
00294
00295
00296 if(target && C_OODing(target))
00297 BTHADD("OODbonus", -2);
00298
00299
00300 if(indirectFire < 1000)
00301 BTHADD("IDFTerrain", indirectFire);
00302
00303
00304 if(MechSpotter(mech) == mech->mynum)
00305 BTHADD("Spotting", 1);
00306
00307
00308 if(target) {
00309
00310 if(MechDugIn(target) && (!mudconf.btech_dig_only_fs || (FindAreaHitGroup(mech, target) == FRONT)) &&
00311 (MechZ(target) >= MechZ(mech)))
00312 BTHADD("DugIn", mudconf.btech_digbonus);
00313
00314
00315 if(IsDS(target))
00316 BTHADD("DSBonus", -3);
00317
00318
00319 if(MechType(target) == CLASS_BSUIT)
00320 BTHADD("Bsuitbonus", 1);
00321
00322
00323 if(target && !IsMissile(weapindx) && MechAim(mech) == HEAD &&
00324 (MechType(target) == CLASS_MECH || MechType(target) == CLASS_MW)) {
00325 if(Immobile(target))
00326 BTHADD("HeadTarget", 7);
00327 else
00328 BTHADD("HeadTarget-Fake", 25);
00329 } else {
00330 if((GetPartFireMode(mech, section, critical) & ON_TC) &&
00331 !(MechCritStatus(mech) & TC_DESTROYED) &&
00332 !(wAmmoMode & LBX_MODE)) {
00333 if(MechAim(mech) != NUM_SECTIONS && !Immobile(target))
00334 BTHADD("TC-Target-NotImmobile", 3);
00335 else
00336 BTHADD("TC", -1);
00337 }
00338 }
00339
00340
00341 if(MechType(mech) == CLASS_AERO) {
00342 wTargMoveMod = TargetMovementMods(mech, target, range) * 3 / 4;
00343 } else {
00344 wTargMoveMod = TargetMovementMods(mech, target, range);
00345 }
00346
00347 if(wAmmoMode & AC_PRECISION_MODE)
00348 wTargMoveMod = MAX(wTargMoveMod -= 2, 0);
00349
00350 if(!(wAmmoMode & SGUIDED_MODE))
00351 BTHADD("TargetMove", wTargMoveMod);
00352 else if ((TaggedBy(target) ? MechTeam(getMech(TaggedBy(target))) == MechTeam(mech) : 0) && wTargMoveMod < 0)
00353 BTHADD("TargetMove", wTargMoveMod);
00354
00355
00356 if(indirectFire >= 1000) {
00357 j = AddTerrainMod(mech, target, mech_map, range, wAmmoMode);
00358 if(j < 1000)
00359 BTHADD("Terrain/Light(Sensor)", j);
00360 }
00361
00362 if(mudconf.btech_moddamagewithwoods &&
00363 IsForestHex(mech_map, MechX(target), MechY(target)) &&
00364 ((MechZ(target) - 2) <= Elevation(mech_map, MechX(target),
00365 MechY(target)))) {
00366 if(GetRTerrain(mech_map, MechX(target),
00367 MechY(target)) == LIGHT_FOREST)
00368 BTHADD("Light Woods bonus", -1);
00369 else if(GetRTerrain(mech_map, MechX(target),
00370 MechY(target)) == HEAVY_FOREST)
00371 BTHADD("Heavy Woods bonus", -2);
00372 }
00373 #ifdef BT_MOVEMENT_MODES
00374 if(MechStatus2(target) & (SPRINTING | EVADING)) {
00375 if(MechStatus2(target) & SPRINTING)
00376 BTHADD("SprintingTarget", -4);
00377 if(!Fallen(target) && MechStatus2(target) & EVADING)
00378 BTHADD("EvadingTarget", 1);
00379
00380
00381
00382
00383 } else if(MoveModeChange(target)) {
00384 int i = MoveModeData(target);
00385 if(i & MODE_SPRINT)
00386 BTHADD("SprintingTargetChanging", -4);
00387 if(i & MODE_EVADE)
00388 BTHADD("EvadingTargetChanging", 1);
00389
00390
00391
00392
00393 }
00394 #endif
00395 }
00396
00397
00398 BTHADD("CritDamage", getCritAddedBTH(mech, section, critical,
00399 wRangeBracket));
00400
00401 BTHEND(mech);
00402 return baseToHit;
00403 }
00404
00405 int FindArtilleryBTH(MECH * mech,
00406 int section, int weapindx, int indirect, float range)
00407 {
00408 int baseToHit = 11;
00409 MECH *spotter;
00410
00411 if(SectionUnderwater(mech, section))
00412 return 5000;
00413
00414 if(EGunRange(weapindx) < range)
00415 return 1000;
00416
00417 baseToHit += (FindPilotArtyGun(mech) - 4);
00418 if(indirect) {
00419 spotter = getMech(MechSpotter(mech));
00420 if(spotter && spotter != mech)
00421 baseToHit += (FindPilotSpotting(spotter) - 4) / 2;
00422
00423 if(indirect && (MechSpotter(mech) == -1 ||
00424 MechSpotter(mech) == mech->mynum))
00425 baseToHit += 1;
00426 } else
00427 baseToHit -= 2;
00428 return baseToHit - MechFireAdjustment(mech);
00429 }
00430
00431 int FindBTHByRange(MECH * mech, MECH * target, int section,
00432 int weapindx, float frange, int firemode, int ammomode,
00433 int *wBTH)
00434 {
00435 int range;
00436 int wTargetStealth = 0;
00437
00438 if(target)
00439 wTargetStealth = (StealthArmorActive(target) ||
00440 NullSigSysActive(target));
00441
00442 if(MechWeapons[weapindx].special & PCOMBAT)
00443 range = (int) (frange * 10 + 0.95);
00444 else
00445 range = (int) (frange + 0.95);
00446
00447 if(SectionUnderwater(mech, section)) {
00448 if(MechWeapons[weapindx].shortrange_water <= 0) {
00449 *wBTH = 5000;
00450 return RANGE_NOWATER;
00451 }
00452
00453
00454 if(range > EGunWaterRange(weapindx)) {
00455 *wBTH = 1000;
00456 return RANGE_TOFAR;
00457 }
00458
00459
00460 if(range > GunWaterRange(weapindx)) {
00461 *wBTH = wTargetStealth ? 12 : 8;
00462 return RANGE_EXTREME;
00463 }
00464
00465
00466 if(range > MechWeapons[weapindx].medrange_water) {
00467 *wBTH = wTargetStealth ? 6 : 4;
00468 return RANGE_LONG;
00469 }
00470
00471
00472 if(range > MechWeapons[weapindx].shortrange_water) {
00473 *wBTH = wTargetStealth ? 3 : 2;
00474 return RANGE_MED;
00475 }
00476
00477
00478 if(range > MechWeapons[weapindx].min_water) {
00479 *wBTH = 0;
00480 return RANGE_SHORT;
00481 }
00482
00483 if(range == 0) {
00484 if(MechWeapons[weapindx].min_water == 0) {
00485 *wBTH = 0;
00486 return RANGE_SHORT;
00487 } else {
00488 *wBTH = MechWeapons[weapindx].min_water - range;
00489 return RANGE_SHORT;
00490 }
00491 }
00492
00493
00494 *wBTH = MechWeapons[weapindx].min_water - range + 1;
00495 }
00496
00497
00498 if(range >
00499 ((ammomode & STINGER_MODE) ? (EGunRange(weapindx) + 7)
00500 : (EGunRange(weapindx)))) {
00501 *wBTH = 1000;
00502 return RANGE_TOFAR;
00503 }
00504
00505
00506 if(range > GunRange(weapindx)) {
00507 *wBTH = wTargetStealth ? 12 : 8;
00508 return RANGE_EXTREME;
00509 }
00510
00511
00512 if(range > MechWeapons[weapindx].medrange) {
00513 *wBTH = wTargetStealth ? 6 : 4;
00514 return RANGE_LONG;
00515 }
00516
00517
00518 if(range > MechWeapons[weapindx].shortrange) {
00519 *wBTH = wTargetStealth ? 3 : 2;
00520 return RANGE_MED;
00521 }
00522
00523
00524 if(range > MechWeapons[weapindx].min) {
00525 *wBTH = 0;
00526 return RANGE_SHORT;
00527 }
00528
00529
00530
00531
00532
00533 if(range == 0) {
00534 if(MechWeapons[weapindx].min == 0) {
00535 *wBTH = 0;
00536 return RANGE_SHORT;
00537 } else {
00538 if(!HotLoading(weapindx, firemode)) {
00539 *wBTH = MechWeapons[weapindx].min - range;
00540 } else {
00541 if(mudconf.btech_hotloadaddshalfbthmod)
00542 *wBTH = ((MechWeapons[weapindx].min - range + 1) / 2);
00543 else
00544 *wBTH = 0;
00545 }
00546
00547 return RANGE_SHORT;
00548 }
00549 }
00550
00551 if(HotLoading(weapindx, firemode)) {
00552 if(mudconf.btech_hotloadaddshalfbthmod)
00553 *wBTH = ((MechWeapons[weapindx].min - range + 1) / 2);
00554 else
00555 *wBTH = 0;
00556
00557 return RANGE_SHORT;
00558 }
00559
00560
00561 *wBTH = MechWeapons[weapindx].min - range + 1;
00562 return RANGE_SHORT;
00563 }
00564
00565 int FindBTHByC3Range(MECH * mech, MECH * target, int section,
00566 int weapindx, float realRange, float c3Range, int mode,
00567 int *wBTH)
00568 {
00569 int realRangeAdj = 0.0;
00570 int c3RangeAdj = 0.0;
00571 int wTargetStealth = 0;
00572
00573 if(target)
00574 wTargetStealth = (StealthArmorActive(target) ||
00575 NullSigSysActive(target));
00576
00577 if(MechWeapons[weapindx].special & PCOMBAT) {
00578 realRangeAdj = (int) (realRange * 10 + 0.95);
00579 c3RangeAdj = (int) (c3Range * 10 + 0.95);
00580 } else {
00581 realRangeAdj = (int) (realRange + 0.95);
00582 c3RangeAdj = (int) (c3Range + 0.95);
00583 }
00584
00585 if(SectionUnderwater(mech, section)) {
00586 if(MechWeapons[weapindx].shortrange_water <= 0) {
00587 *wBTH = 5000;
00588 return RANGE_NOWATER;
00589 }
00590
00591
00592 if(realRangeAdj > GunWaterRange(weapindx)) {
00593 *wBTH = 1000;
00594 return RANGE_TOFAR;
00595 }
00596
00597
00598 if(c3RangeAdj > MechWeapons[weapindx].medrange_water) {
00599 *wBTH = wTargetStealth ? 6 : 4;
00600 return RANGE_LONG;
00601 }
00602
00603
00604 if(c3RangeAdj > MechWeapons[weapindx].shortrange_water) {
00605 *wBTH = wTargetStealth ? 3 : 2;
00606 return RANGE_MED;
00607 }
00608
00609
00610 *wBTH = 0;
00611 return RANGE_SHORT;
00612 }
00613
00614
00615 if(realRangeAdj > GunRange(weapindx)) {
00616 *wBTH = 1000;
00617 return RANGE_TOFAR;
00618 }
00619
00620
00621
00622 if(c3RangeAdj > MechWeapons[weapindx].medrange) {
00623 *wBTH = wTargetStealth ? 6 : 4;
00624 return RANGE_LONG;
00625 }
00626
00627
00628 if(c3RangeAdj > MechWeapons[weapindx].shortrange) {
00629 *wBTH = wTargetStealth ? 3 : 2;
00630 return RANGE_MED;
00631 }
00632
00633
00634 if(realRange > MechWeapons[weapindx].min) {
00635 *wBTH = 0;
00636 return RANGE_SHORT;
00637 }
00638
00639
00640 if(c3RangeAdj == 0) {
00641 if(MechWeapons[weapindx].min == 0) {
00642 *wBTH = 0;
00643 return RANGE_SHORT;
00644 }
00645 }
00646
00647
00648 if(!HotLoading(weapindx, mode)) {
00649 if(mudconf.btech_hotloadaddshalfbthmod)
00650 *wBTH = ((MechWeapons[weapindx].min - realRange + 1) / 2);
00651 else
00652 *wBTH = 0;
00653
00654 return RANGE_SHORT;
00655 }
00656
00657
00658 *wBTH = MechWeapons[weapindx].min - realRange + 1;
00659 return RANGE_SHORT;
00660 }
00661
00662 int AttackMovementMods(MECH * mech)
00663 {
00664 float maxspeed;
00665 float speed;
00666 int base = 0;
00667
00668 if(MechType(mech) == CLASS_BSUIT)
00669 return 0;
00670
00671 maxspeed = MechMaxSpeed(mech);
00672 if((MechHeat(mech) >= 9.) && (MechSpecials(mech) & TRIPLE_MYOMER_TECH))
00673 maxspeed += 1.5 * MP1;
00674 if(Jumping(mech))
00675 return 3;
00676
00677
00678 if((!MechIsQuad(mech) || (MechIsQuad(mech) &&
00679 CountDestroyedLegs(mech) > 0)) && Fallen(mech)
00680 && !IsDS(mech))
00681 return 2;
00682
00683 if(!Jumping(mech) && (Stabilizing(mech) || Standing(mech)))
00684 return 2;
00685
00686 if(fabs(MechSpeed(mech)) > fabs(MechDesiredSpeed(mech)))
00687 speed = MechSpeed(mech);
00688 else
00689 speed = MechDesiredSpeed(mech);
00690
00691 if(mudconf.btech_fasaturn)
00692 if(MechFacing(mech) != MechDesiredFacing(mech))
00693 base++;
00694
00695 if(!(fabs(speed) > 0.0))
00696 return base + 0;
00697 if(IsRunning(speed, maxspeed))
00698 return 2;
00699 return base + 1;
00700 }
00701
00702 int TargetMovementMods(MECH * mech, MECH * target, float range)
00703 {
00704 float target_speed = 0.0;
00705 int returnValue = 0;
00706 float m = 1.0;
00707 MAP *map = FindObjectsData(target->mapindex);
00708 MECH *swarmTarget;
00709
00710 if(is_aero(target)) {
00711 if(is_aero(mech))
00712 m = ACCEL_MOD;
00713 target_speed =
00714 (float) length_hypotenuse((double) MechSpeed(target) / m,
00715 (double) MechVerticalSpeed(target) / m);
00716 } else {
00717 if(Jumping(target)) {
00718 target_speed = JumpSpeed(target, map);
00719 } else if(MechSwarmTarget(target) > 0) {
00720 if((swarmTarget = getMech(MechSwarmTarget(target)))) {
00721 if(Jumping(swarmTarget))
00722 target_speed = JumpSpeed(swarmTarget, map);
00723 else
00724 target_speed = fabs(MechSpeed(swarmTarget));
00725 }
00726 } else {
00727 target_speed = fabs(MechSpeed(target));
00728 }
00729 }
00730
00731 if(MechInfantrySpecials(target) & CS_PURIFIER_STEALTH_TECH) {
00732 if(target_speed == 0.0) {
00733
00734 returnValue = 3;
00735 } else if(target_speed <= MP1) {
00736
00737 returnValue = 2;
00738 } else if(target_speed <= MP2) {
00739
00740 returnValue = 1;
00741 } else {
00742 returnValue = 0;
00743 }
00744 } else {
00745 if(target_speed <= MP2) {
00746
00747 returnValue = 0;
00748 } else if(target_speed <= MP4) {
00749
00750 returnValue = 1;
00751 } else if(target_speed <= MP6) {
00752
00753 returnValue = 2;
00754 } else if(target_speed <= MP9) {
00755
00756 returnValue = 3;
00757 } else {
00758
00759 if(mudconf.btech_extendedmovemod)
00760 returnValue = 4 + (target_speed - 10 * MP1) / MP4;
00761 else
00762 returnValue = 4;
00763 }
00764 }
00765
00766 if(Immobile(target))
00767 returnValue += -4;
00768
00769 if(Fallen(target) && ((MechType(target) == CLASS_MECH) ||
00770 (MechType(target) == CLASS_MW)))
00771 returnValue += (range <= 1.0) ? -2 : 1;
00772
00773 if(Jumping(target))
00774 returnValue++;
00775
00776 return (returnValue);
00777 }