/*
* $Id: mech.bth.c,v 1.2 2005/06/23 15:27:04 av1-op Exp $
*
* Author: Cord Awtry <kipsta@mediaone.net>
* Author: Cord Awtry <kipsta@mediaone.net>
* Copyright (c) 2000-2002 Cord Awtry
* Copyright (c) 1999-2005 Kevin Stevens
* All rights reserved
*
* Based on work that was:
* Copyright (c) 1997 Markus Stenberg
* Copyright (c) 1998-2000 Thomas Wouters
*/
#include <math.h>
#include "mech.h"
#include "mech.events.h"
#include "p.mech.bth.h"
#include "p.mech.c3.misc.h"
#include "p.mech.combat.h"
#include "p.mech.enhanced.criticals.h"
#include "p.mech.hitloc.h"
#include "p.mech.los.h"
#include "p.mech.update.h"
#include "p.mech.utils.h"
#ifndef BTH_DEBUG
#define BTHBASE(m,t,n) baseToHit = n;
#define BTHADD(desc,n) baseToHit += n;
#define BTHEND(m)
#else
#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)
#define BTHADD(desc,n) do { i = n ; if (i) { sprintf(buf+strlen(buf), ", %s: %s%d", desc, i>0 ? "+" : "", i); baseToHit += i; } } while (0)
#define BTHEND(m) SendBTHDebug(tprintf("%s.", buf))
#endif
int arc_override;
int FindNormalBTH(MECH * mech,
MAP * mech_map,
int section,
int critical,
int weapindx, float range, MECH * target, int indirectFire,
dbref * c3Ref)
{
MECH *spotter = NULL;
int baseToHit;
int wFireMode = GetPartFireMode(mech, section, critical);
int wAmmoMode = GetPartAmmoMode(mech, section, critical);
int tInWater = 0;
int tTargetInWater = 0;
int wTargMoveMod = 0;
#ifdef BTH_DEBUG
char buf[LBUF_SIZE];
int i;
#endif
int j, rbth = 0;
float enemyX, enemyY, enemyZ;
int wRangeBracket = RANGE_TOFAR;
*c3Ref = -1;
if (target) {
tInWater = ((MechRTerrain(mech) == WATER) && (MechZ(mech) < 0));
tTargetInWater = ((MechRTerrain(target) == WATER) &&
(MechZ(target) < 0));
}
BTHBASE(mech, target, FindPilotGunnery(mech, weapindx));
if (indirectFire < 1000) {
spotter = getMech(MechSpotter(mech));
if (!spotter) {
mech_notify(mech, MECHALL,
"Error finding your spotter! (notify a wiz)");
return 0;
}
BTHADD("Spotting", FindPilotSpotting(spotter) - 4);
}
/* Our special bother for aeros */
if (is_aero(mech) && target && !is_aero(target) && !Landed(mech)) {
BTHADD("Aero strafing", 2);
};
/* MW need +2 added per FASA */
if (target && MechType(target) == CLASS_MW)
BTHADD("MechWarrior", 2);
/* add in to-hit mods from criticals */
BTHADD("MechBTHMod", MechBTH(mech));
/* add in to-hit mods for section damage */
BTHADD("MechLocBTHMod", MechSections(mech)[section].basetohit);
/* Add +1 if we're firing from water */
if (tInWater)
BTHADD("InWater", 1);
/* Add in the rangebase.. */
if (EGunRange(weapindx) < range) {
BTHADD("OutOfRange", 1000);
} else {
if ((MechWeapons[weapindx].min >= range) &&
(MechWeapons[weapindx].min > 0)) {
if (!HotLoading(weapindx, GetPartFireMode(mech, section,
critical))) {
/* if the target is in minimum range then the BTH is as good as it will get */
rbth = (MechWeapons[weapindx].min - range + 1);
} else {
if (mudconf.btech_hotloadaddshalfbthmod) {
rbth = ((MechWeapons[weapindx].min - range + 2) / 2);
}
}
BTHADD("MinRange", rbth);
} else if (HasC3(mech) && !C3Destroyed(mech) &&
!AnyECMDisturbed(mech) && (MechC3NetworkSize(mech) > 0)) {
wRangeBracket = FindBTHByC3Range(mech, target,
section, weapindx, range,
findC3Range(mech, target, range, c3Ref, 1), wAmmoMode,
&rbth);
BTHADD("C3Range", rbth);
} else if (HasC3i(mech) && !C3iDestroyed(mech) &&
!AnyECMDisturbed(mech) && (MechC3iNetworkSize(mech) > 0)) {
wRangeBracket = FindBTHByC3Range(mech, target,
section, weapindx, range,
findC3Range(mech, target, range, c3Ref, 0), wAmmoMode,
&rbth);
BTHADD("C3iRange", rbth);
} else {
wRangeBracket = FindBTHByRange(mech, target, section,
weapindx, range, wFireMode, &rbth);
BTHADD("Range", rbth);
}
}
/* I decided to put it here in this rewritten form. To add it to FindBTH*() was a bit
* convoluted compared to original source method, Exile and 3030/btechmux went a few
* different path's on internal representation and organization of various weapon data
* and BTH handling. Someday I might, after I review how some of the same things were
* done here, port some of that stuff over. (Like GunStat() and such)
*
* For now we just do the below stuff. Besides, it might make BTH debug more obvious
* that putting it into FindBTH*().
*/
if (MechTargComp(mech) == TARGCOMP_SHORT || MechTargComp(mech) == TARGCOMP_LONG) {
int tmp_range;
if (MechWeapons[weapindx].special & PCOMBAT)
tmp_range = (int) (range * 10 + 0.95);
else
tmp_range = (int) (range + 0.95);
if (tmp_range >
(SectionUnderwater(mech, section) ? GunWaterRange(weapindx) : GunRange(weapindx)))
BTHADD("TargComp/Long", MechTargComp(mech) == TARGCOMP_LONG ? -1 : 1);
else if (tmp_range <=
(SectionUnderwater(mech, section) ? MechWeapons[weapindx].medrange_water : MechWeapons[weapindx].medrange))
BTHADD("TargComp/Short", MechTargComp(mech) == TARGCOMP_SHORT ? -1 : 1);
}
if (target && MechInfantrySpecials(target) & STEALTH_TECH) {
if (MechInfantrySpecials(target) & FWL_ACHILEUS_STEALTH_TECH) {
if (wRangeBracket == RANGE_SHORT)
BTHADD("FWLStealthBonus", 1);
else if (wRangeBracket == RANGE_MED)
BTHADD("FWLStealthBonus", 2);
else if (wRangeBracket == RANGE_LONG)
BTHADD("FWLStealthBonus", 3);
} else if (MechInfantrySpecials(target) & DC_KAGE_STEALTH_TECH) {
if (wRangeBracket == RANGE_MED)
BTHADD("DCStealthBonus", 1);
else if (wRangeBracket == RANGE_LONG)
BTHADD("DCStealthBonus", 2);
} else if (MechInfantrySpecials(target) &
FC_INFILTRATOR_STEALTH_TECH) {
if (wRangeBracket == RANGE_MED)
BTHADD("FCStealthBonus", 1);
else if (wRangeBracket == RANGE_LONG)
BTHADD("FCStealthBonus", 2);
} else if (MechInfantrySpecials(target) &
FC_INFILTRATORII_STEALTH_TECH) {
if (wRangeBracket == RANGE_SHORT)
BTHADD("FCStealthIIBonus", 1);
if (wRangeBracket == RANGE_MED)
BTHADD("FCStealthIIBonus", 1);
else if (wRangeBracket == RANGE_LONG)
BTHADD("FCStealthIIBonus", 2);
}
}
/* Add in the movement modifiers */
if (MechSections(mech)[section].config & STABILIZERS_DESTROYED)
BTHADD("AttackMoveX2", AttackMovementMods(mech) * 2);
else
BTHADD("AttackMove", AttackMovementMods(mech));
/* Add mods for overheating */
BTHADD("Overheat", OverheatMods(mech));
/* Add special weapon mods */
if (wAmmoMode & AC_AP_MODE)
BTHADD("ArmorPiercing", 1);
if (checkAllSections(mech, INARC_HAYWIRE_ATTACHED))
BTHADD("HaywirePod", 1);
if (target && (wAmmoMode & NARC_MODE) &&
(!(MechWeapons[weapindx].special & NARC)) &&
checkAllSections(target, INARC_HOMING_ATTACHED))
BTHADD("iNARC", -1);
if (MechWeapons[weapindx].special & PULSE)
BTHADD("Pulse", -2);
if (MechWeapons[weapindx].special & MRM)
BTHADD("MRM", 1);
if (MechWeapons[weapindx].special & HVYW)
BTHADD("HeavyWeapon", 1);
if (MechWeapons[weapindx].special & ROCKET)
BTHADD("Rocket Launcher", 1);
if (target && (MechType(target) == CLASS_VTOL) &&
(fabs(MechSpeed(target)) > 0.0 ||
fabs(MechVerticalSpeed(target)) > 0.0))
BTHADD("TargetVTOL", 1);
if (target && MechTargComp(mech) == TARGCOMP_AA) {
if (!Landed(target) && (FlyingT(target) || Jumping(target) || OODing(target)))
BTHADD("TargComp/AA-Fly", MechSpecials(mech) & AA_TECH ? -3 : -2);
else
BTHADD("TargComp/AA-Ground", 1);
}
/* -1 for LBX, unless it's a VTOL... then -3 */
if (wAmmoMode & LBX_MODE)
BTHADD("LBX", (target &&
(MechType(target) == CLASS_VTOL) ? -3 : -1));
/* Unstable lock */
if (!arc_override && (!spotter && target &&
((MechTarget(mech) != target->mynum) ||
(Locking(mech) && MechTargComp(mech) != TARGCOMP_MULTI)))) {
if (FindTargetXY(mech, &enemyX, &enemyY, &enemyZ)) {
if (InWeaponArc(mech, enemyX, enemyY) & (FORWARDARC|TURRETARC))
BTHADD("UnstableLock/Fwarc", 1);
else
BTHADD("UnstableLock", 2);
} else {
BTHADD("HipShot-NoLock", 2);
}
}
if (MechTargComp(mech) == TARGCOMP_MULTI) {
if (FindTargetXY(mech, &enemyX, &enemyY, &enemyZ)) {
if (!(InWeaponArc(mech, enemyX, enemyY) & FORWARDARC))
BTHADD("TargComp/MultiSideArc", 1);
}
}
/* -4 for firing at a hex */
if (!target &&
(MechStatus(mech) & (LOCK_HEX | LOCK_BUILDING | LOCK_HEX_IGN |
LOCK_HEX_CLR)))
BTHADD("HexBonus", -4);
/* -2 for firing at someone dropping out of the sky */
if (target && C_OODing(target))
BTHADD("OODbonus", -2);
/* Indirect fire terrain modifiers */
if (indirectFire < 1000)
BTHADD("IDFTerrain", indirectFire);
/* +1 if spotting */
if (MechSpotter(mech) == mech->mynum)
BTHADD("Spotting", 1);
/* if our target is another unit... */
if (target) {
/* Add the dig-in bonus */
if (MechDugIn(target) && (!mudconf.btech_dig_only_fs &&
(FindAreaHitGroup(mech, target) == FRONT)) &&
(MechZ(target) >= MechZ(mech)))
BTHADD("DugIn", mudconf.btech_digbonus);
/* -3 if it's a DS... most people can hit the broadside of a barn */
if (IsDS(target))
BTHADD("DSBonus", -3);
/* Add +1 for BSuit dispersion */
if (MechType(target) == CLASS_BSUIT)
BTHADD("Bsuitbonus", 1);
/* Let's see if we're targetting the head */
if (target && !IsMissile(weapindx) &&
(((MechAim(mech) == HEAD) && ((MechType(target) == CLASS_MECH)
|| (MechType(target) == CLASS_MW))) ||
((MechAim(mech) == AERO_COCKPIT) &&
(MechType(target) == CLASS_AERO)))) {
if (Immobile(target))
BTHADD("HeadTarget", 7);
else
BTHADD("HeadTarget-Fake", 25);
} else {
if ((GetPartFireMode(mech, section, critical) & ON_TC) &&
!(MechCritStatus(mech) & TC_DESTROYED) &&
!(wAmmoMode & LBX_MODE)) {
if (MechAim(mech) != NUM_SECTIONS && !Immobile(target))
BTHADD("TC-Target-NotImmobile", 3);
else
BTHADD("TC", -1);
}
}
/* Add aero targetting mods. TODO: Rewrite aero code :) */
if (MechType(mech) == CLASS_AERO) {
wTargMoveMod = TargetMovementMods(mech, target, range) * 3 / 4;
} else {
wTargMoveMod = TargetMovementMods(mech, target, range);
}
if (wAmmoMode & AC_PRECISION_MODE)
wTargMoveMod = MAX(wTargMoveMod -= 2, 0);
BTHADD("TargetMove", wTargMoveMod);
/* Add in the terrain modifier */
if (indirectFire >= 1000) {
j = AddTerrainMod(mech, target, mech_map, range, wAmmoMode);
if (j < 1000)
BTHADD("Terrain/Light(Sensor)", j);
}
if (mudconf.btech_moddamagewithwoods &&
IsForestHex(mech_map, MechX(target), MechY(target)) &&
((MechZ(target) - 2) <= Elevation(mech_map, MechX(target),
MechY(target)))) {
if (GetRTerrain(mech_map, MechX(target),
MechY(target)) == LIGHT_FOREST)
BTHADD("Light Woods bonus", -1);
else if (GetRTerrain(mech_map, MechX(target),
MechY(target)) == HEAVY_FOREST)
BTHADD("Heavy Woods bonus", -2);
}
#ifdef BT_MOVEMENT_MODES
if (MechStatus2(target) & (SPRINTING|EVADING)) {
if (MechStatus2(target) & SPRINTING)
BTHADD("SprintingTarget", -4);
if (!Fallen(target) && MechStatus2(target) & EVADING)
BTHADD("EvadingTarget", 1);
/* BTHADD("EvadingTarget", (FindPilotPiloting(target) >= 6 ? 1 :
FindPilotPiloting(target) >= 4 ? 2 :
FindPilotPiloting(target) >= 2 ? 3 : 4) +
(HasBoolAdvantage(MechPilot(target), "speed_demon") ? 1 : 0)); */
} else if (MoveModeChange(target)) {
int i = MoveModeData(target);
if (i & MODE_SPRINT)
BTHADD("SprintingTargetChanging", -4);
if (i & MODE_EVADE)
BTHADD("EvadingTargetChanging", 1);
/* BTHADD("EvadingTarget", (FindPilotPiloting(target) >= 6 ? 1 :
FindPilotPiloting(target) >= 4 ? 2 :
FindPilotPiloting(target) >= 2 ? 3 : 4) +
(HasBoolAdvantage(MechPilot(target), "speed_demon") ? 1 : 0)); */
}
#endif
}
/* Check for damage */
BTHADD("CritDamage", getCritAddedBTH(mech, section, critical,
wRangeBracket));
BTHEND(mech);
return baseToHit;
}
int FindArtilleryBTH(MECH * mech,
int section, int weapindx, int indirect, float range)
{
int baseToHit = 11;
MECH *spotter;
if (SectionUnderwater(mech, section))
return 5000;
if (EGunRange(weapindx) < range)
return 1000;
baseToHit += (FindPilotArtyGun(mech) - 4);
if (indirect) {
spotter = getMech(MechSpotter(mech));
if (spotter && spotter != mech)
baseToHit += (FindPilotSpotting(spotter) - 4) / 2;
/* the usual +2, added by +1 make +3 */
if (indirect && (MechSpotter(mech) == -1 ||
MechSpotter(mech) == mech->mynum))
baseToHit += 1;
} else
baseToHit -= 2;
return baseToHit - MechFireAdjustment(mech);
}
int FindBTHByRange(MECH * mech, MECH * target, int section,
int weapindx, float frange, int mode, int *wBTH)
{
int range;
int wTargetStealth = 0;
if (target)
wTargetStealth = (StealthArmorActive(target) ||
NullSigSysActive(target));
if (MechWeapons[weapindx].special & PCOMBAT)
range = (int) (frange * 10 + 0.95);
else
range = (int) (frange + 0.95);
if (SectionUnderwater(mech, section)) {
if (MechWeapons[weapindx].shortrange_water <= 0) {
*wBTH = 5000;
return RANGE_NOWATER;
}
/* Out of range range */
if (range > EGunWaterRange(weapindx)) {
*wBTH = 1000;
return RANGE_TOFAR;
}
/* Very long range */
if (range > GunWaterRange(weapindx)) {
*wBTH = wTargetStealth ? 12 : 8;
return RANGE_EXTREME;
}
/* Long range... */
if (range > MechWeapons[weapindx].medrange_water) {
*wBTH = wTargetStealth ? 6 : 4;
return RANGE_LONG;
}
/* Medium range */
if (range > MechWeapons[weapindx].shortrange_water) {
*wBTH = wTargetStealth ? 3 : 2;
return RANGE_MED;
}
/* Short range */
if (range > MechWeapons[weapindx].min_water) {
*wBTH = 0;
return RANGE_SHORT;
}
if (range == 0) {
if (MechWeapons[weapindx].min_water == 0) {
*wBTH = 0;
return RANGE_SHORT;
} else {
*wBTH = MechWeapons[weapindx].min_water - range;
return RANGE_SHORT;
}
}
/* Less than or equal to minimum range */
*wBTH = MechWeapons[weapindx].min_water - range + 1;
}
/* Beyond range */
if (range > EGunRange(weapindx)) {
*wBTH = 1000;
return RANGE_TOFAR;
}
/* V. Long range */
if (range > GunRange(weapindx)) {
*wBTH = wTargetStealth ? 12 : 8;
return RANGE_EXTREME;
}
/* Long range... */
if (range > MechWeapons[weapindx].medrange) {
*wBTH = wTargetStealth ? 6 : 4;
return RANGE_LONG;
}
/* Medium range */
if (range > MechWeapons[weapindx].shortrange) {
*wBTH = wTargetStealth ? 3 : 2;
return RANGE_MED;
}
/* Short range */
if (range > MechWeapons[weapindx].min) {
*wBTH = 0;
return RANGE_SHORT;
}
/* If we are at range 0.0
* Added 8/3/99 by Kipsta (to fix a 0.0 bug)
*/
if (range == 0) {
if (MechWeapons[weapindx].min == 0) {
*wBTH = 0;
return RANGE_SHORT;
} else {
if (!HotLoading(weapindx, mode)) {
*wBTH = MechWeapons[weapindx].min - range;
} else {
if (mudconf.btech_hotloadaddshalfbthmod)
*wBTH = ((MechWeapons[weapindx].min - range + 1) / 2);
else
*wBTH = 0;
}
return RANGE_SHORT;
}
}
if (HotLoading(weapindx, mode)) {
if (mudconf.btech_hotloadaddshalfbthmod)
*wBTH = ((MechWeapons[weapindx].min - range + 1) / 2);
else
*wBTH = 0;
return RANGE_SHORT;
}
/* Less than or equal to minimum range */
*wBTH = MechWeapons[weapindx].min - range + 1;
return RANGE_SHORT;
}
int FindBTHByC3Range(MECH * mech, MECH * target, int section,
int weapindx, float realRange, float c3Range, int mode, int *wBTH)
{
int realRangeAdj = 0.0;
int c3RangeAdj = 0.0;
int wTargetStealth = 0;
if (target)
wTargetStealth = (StealthArmorActive(target) ||
NullSigSysActive(target));
if (MechWeapons[weapindx].special & PCOMBAT) {
realRangeAdj = (int) (realRange * 10 + 0.95);
c3RangeAdj = (int) (c3Range * 10 + 0.95);
} else {
realRangeAdj = (int) (realRange + 0.95);
c3RangeAdj = (int) (c3Range + 0.95);
}
if (SectionUnderwater(mech, section)) {
if (MechWeapons[weapindx].shortrange_water <= 0) {
*wBTH = 5000;
return RANGE_NOWATER;
}
/* Out of range. No ERange in C3 */
if (realRangeAdj > GunWaterRange(weapindx)) {
*wBTH = 1000;
return RANGE_TOFAR;
}
/* Long range... */
if (c3RangeAdj > MechWeapons[weapindx].medrange_water) {
*wBTH = wTargetStealth ? 6 : 4;
return RANGE_LONG;
}
/* Medium range */
if (c3RangeAdj > MechWeapons[weapindx].shortrange_water) {
*wBTH = wTargetStealth ? 3 : 2;
return RANGE_MED;
}
/* Short range */
*wBTH = 0;
return RANGE_SHORT;
}
/* Beyond range */
if (realRangeAdj > GunRange(weapindx)) {
*wBTH = 1000;
return RANGE_TOFAR;
}
/* No V. Long range in a C3 network */
/* Long range... */
if (c3RangeAdj > MechWeapons[weapindx].medrange) {
*wBTH = wTargetStealth ? 6 : 4;
return RANGE_LONG;
}
/* Medium range */
if (c3RangeAdj > MechWeapons[weapindx].shortrange) {
*wBTH = wTargetStealth ? 3 : 2;
return RANGE_MED;
}
/* Short range */
if (realRange > MechWeapons[weapindx].min) {
*wBTH = 0;
return RANGE_SHORT;
}
/* Check for range 0.0 */
if (c3RangeAdj == 0) {
if (MechWeapons[weapindx].min == 0) {
*wBTH = 0;
return RANGE_SHORT;
}
}
/* We don't care about min range if we're Hotloading */
if (!HotLoading(weapindx, mode)) {
if (mudconf.btech_hotloadaddshalfbthmod)
*wBTH = ((MechWeapons[weapindx].min - realRange + 1) / 2);
else
*wBTH = 0;
return RANGE_SHORT;
}
/* Less than or equal to minimum PHYSICAL range */
*wBTH = MechWeapons[weapindx].min - realRange + 1;
return RANGE_SHORT;
}
int AttackMovementMods(MECH * mech)
{
float maxspeed;
float speed;
int base = 0;
if (MechType(mech) == CLASS_BSUIT)
return 0;
maxspeed = MechMaxSpeed(mech);
if ((MechHeat(mech) >= 9.) &&
(MechSpecials(mech) & TRIPLE_MYOMER_TECH))
maxspeed += 1.5 * MP1;
if (Jumping(mech))
return 3;
/* quads don't suffer the +2 BTH firing while prone if they have all 4 legs */
if ((!MechIsQuad(mech) || (MechIsQuad(mech) &&
CountDestroyedLegs(mech) > 0)) && Fallen(mech) &&
!IsDS(mech))
return 2;
if (!Jumping(mech) && (Stabilizing(mech) || Standing(mech)))
return 2;
if (fabs(MechSpeed(mech)) > fabs(MechDesiredSpeed(mech)))
speed = MechSpeed(mech);
else
speed = MechDesiredSpeed(mech);
if (mudconf.btech_fasaturn)
if (MechFacing(mech) != MechDesiredFacing(mech))
base++;
if (!(fabs(speed) > 0.0))
return base + 0;
if (IsRunning(speed, maxspeed))
return 2;
return base + 1;
}
int TargetMovementMods(MECH * mech, MECH * target, float range)
{
float target_speed = 0.0;
int returnValue = 0;
float m = 1.0;
MAP *map = FindObjectsData(target->mapindex);
MECH *swarmTarget;
if (is_aero(target)) {
if (is_aero(mech))
m = ACCEL_MOD;
target_speed =
(float) length_hypotenuse((double) MechSpeed(target) / m,
(double) MechVerticalSpeed(target) / m);
} else {
if (Jumping(target)) {
target_speed = JumpSpeed(target, map);
} else if (MechSwarmTarget(target) > 0) {
if ((swarmTarget = getMech(MechSwarmTarget(target)))) {
if (Jumping(swarmTarget))
target_speed = JumpSpeed(swarmTarget, map);
else
target_speed = fabs(MechSpeed(swarmTarget));
}
} else {
target_speed = fabs(MechSpeed(target));
}
}
if (MechInfantrySpecials(target) & CS_PURIFIER_STEALTH_TECH) {
if (target_speed == 0.0) {
/* Mech moved 0-2 hexes */
returnValue = 3;
} else if (target_speed <= MP1) {
/* Mech moved 3-4 hexes */
returnValue = 2;
} else if (target_speed <= MP2) {
/* Mech moved 5-6 hexes */
returnValue = 1;
} else {
returnValue = 0;
}
} else {
if (target_speed <= MP2) {
/* Mech moved 0-2 hexes */
returnValue = 0;
} else if (target_speed <= MP4) {
/* Mech moved 3-4 hexes */
returnValue = 1;
} else if (target_speed <= MP6) {
/* Mech moved 5-6 hexes */
returnValue = 2;
} else if (target_speed <= MP9) {
/* Mech moved 7-9 hexes */
returnValue = 3;
} else {
/* Moving more than 9 hexes */
if (mudconf.btech_extendedmovemod)
returnValue = 4 + (target_speed - 10*MP1) / MP4;
else
returnValue = 4;
}
}
if (Immobile(target))
returnValue += -4;
if (Fallen(target) && ((MechType(target) == CLASS_MECH) ||
(MechType(target) == CLASS_MW)))
returnValue += (range <= 1.0) ? -2 : 1;
if (Jumping(target))
returnValue++;
return (returnValue);
}