btmux-0.6-rc4/doc/
btmux-0.6-rc4/event/
btmux-0.6-rc4/game/
btmux-0.6-rc4/game/maps/
btmux-0.6-rc4/game/mechs/
btmux-0.6-rc4/game/text/help/
btmux-0.6-rc4/game/text/help/cat_faction/
btmux-0.6-rc4/game/text/help/cat_inform/
btmux-0.6-rc4/game/text/help/cat_misc/
btmux-0.6-rc4/game/text/help/cat_mux/
btmux-0.6-rc4/game/text/help/cat_mux/cat_commands/
btmux-0.6-rc4/game/text/help/cat_mux/cat_functions/
btmux-0.6-rc4/game/text/help/cat_templates/
btmux-0.6-rc4/game/text/wizhelp/
btmux-0.6-rc4/include/
btmux-0.6-rc4/misc/
btmux-0.6-rc4/python/
btmux-0.6-rc4/src/hcode/btech/
btmux-0.6-rc4/tree/
/*
 * $Id: mech.sensor.functions.c,v 1.1.1.1 2005/01/11 21:18:23 kstevens Exp $
 *
 * Author: Markus Stenberg <fingon@iki.fi>
 *
 *  Copyright (c) 1996 Markus Stenberg
 *  Copyright (c) 1998-2002 Thomas Wouters
 *  Copyright (c) 2000-2002 Cord Awtry
 *       All rights reserved
 *
 * Created: Mon Sep  2 16:57:30 1996 fingon
 * Last modified: Tue Oct  6 17:21:27 1998 fingon
 *
 */

#include "mech.h"
#include "mech.sensor.h"
#include "p.map.obj.h"
#include "p.mech.update.h"
#include "p.mech.utils.h"
#include "p.template.h"

/* Full chance of seeing, except if range > conditionrange */
SEEFUNC(vislight_see, r > (c * ((!l && t &&
								 IsLit(t)) ? 3 : 1)) ? 0 : (100 -
															(r / 3)) / ((t
																		 &&
																		 (MechType
																		  (t)
																		  ==
																		  CLASS_BSUIT
																		  ||
																		  MechType
																		  (t)
																		  ==
																		  CLASS_MW))
																		? 3 :
																		1));

/* In perfect darkness, 2x conditionrange. Otherwise conditionrange,
   always same chance of seeing */
SEEFUNC(liteamp_see, ((!l && r > (2 * c)) ? 0 : (l &&
												 r > c) ? 0 : (70 - r)) / ((t
																			&&
																			(MechType
																			 (t)
																			 ==
																			 CLASS_BSUIT
																			 ||
																			 MechType
																			 (t)
																			 ==
																			 CLASS_MW))
																		   ? 3
																		   :
																		   1));

/* Always same chance, if within range */
SEEFUNC(infrared_see, (80 - r));
SEEFUNC(electrom_see, MAX(r < 24 ? 2 : 0, (60 - (r * 2))) / 2);
SEEFUNC(seismic_see, 50 - (r * 4));

SEEFUNC(radar_see, BOUNDED(10, (180 - r), 90));
SEEFUNC(bap_see, 101);
SEEFUNC(blood_see, 101);

/* Prior requirement: the seechance > 0. We assume it so,
   and only examine the flag. */

extern float ActualElevation(MAP * map, int x, int y, MECH * mech);

/* Visual methods are hampered by excess woods / water */
CSEEFUNC(vislight_csee, !(map->sensorflags & (1 << SENSOR_VIS)) &&
		 !(f & (MECHLOSFLAG_BLOCK | MECHLOSFLAG_FIRE | MECHLOSFLAG_SMOKE)) &&
		 MechLOSFlag_WoodCount(f) < 3 && (!t || MechZ(t) >= 0 ||
										  ActualElevation(getMap(t->mapindex),
														  MechX(t), MechY(t),
														  t) >= 0.0
										  || MechLOSFlag_WaterCount(f) < 6));

/* Liteamp doesn't see into water, thanks to reflections etc */
CSEEFUNC(liteamp_csee, !(map->sensorflags & (1 << SENSOR_LA)) &&
		 !(f & (MECHLOSFLAG_BLOCK | MECHLOSFLAG_FIRE | MECHLOSFLAG_SMOKE)) &&
		 (!t || !IsLit(t)) && MechLOSFlag_WoodCount(f) < 2
		 && !(MechLOSFlag_WaterCount(f)));

/* Not too good with woods, infra.. too much variation in temperature */
CSEEFUNC(infrared_csee, !(map->sensorflags & (1 << SENSOR_IR)) &&
		 !(f & (MECHLOSFLAG_BLOCK | MECHLOSFLAG_FIRE)) &&
		 MechLOSFlag_WoodCount(f) < 6 && (!t || (MechType(t) != CLASS_BSUIT &&
												 MechType(t) != CLASS_MW)));

/* Mountains provide too much hindarance in terms of electromagnetic
   detection */
CSEEFUNC(electrom_csee, !(map->sensorflags & (1 << SENSOR_EM)) &&
		 !(f & (MECHLOSFLAG_BLOCK | MECHLOSFLAG_MNTN)) &&
		 MechLOSFlag_WoodCount(f) < 8 && !AnyECMDisturbed(m) && (!t ||
																 (MechType(t)
																  !=
																  CLASS_MW)));

/* Seismic sees, as long as there is a target, and it isn't jumping or
   flying, or hovering, or otherwise with little or no contact to the
   ground. Period. */
CSEEFUNC(seismic_csee,
		 !(map->sensorflags & (1 << SENSOR_SE)) &&
		 t && (!Jumping(m)) &&
		 (mudconf.btech_seismic_see_stopped ? 1 : (abs(MechSpeed(t)) > MP1))
		 &&
		 (((MechMove(m) != MOVE_VTOL)
		   || ((MechMove(m) == MOVE_VTOL) && Landed(m)))
		  && ((MechMove(m) != MOVE_FLY)
			  || ((MechMove(m) == MOVE_FLY) && Landed(m))) && Started(t)
		  && !Jumping(t) && (MechType(t) != CLASS_BSUIT)
		  && (MechType(t) != CLASS_MW) && (MechMove(t) != MOVE_HOVER)
		  && ((MechMove(t) != MOVE_VTOL)
			  || ((MechMove(t) == MOVE_VTOL) && Landed(t)))
		  && ((MechMove(t) != MOVE_FLY)
			  || ((MechMove(t) == MOVE_FLY) && Landed(t))))
		 && (MechMove(t) != MOVE_NONE));

/* Radar sees, as long as the target is flying and not near disruptions. */
CSEEFUNC(radar_csee,
		 !(map->sensorflags & (1 << SENSOR_RA)) &&
		 t &&
		 MechZ(t) > 2 &&
		 !(f & MECHLOSFLAG_BLOCK) &&
		 (MechZ(t) >= 10 || (r < (MechZ(t) * MechZ(t)))) &&
		 MechsElevation(t) > 1);

/* BAP is disrupted by ECM and can't pick up units with nullsig active. */
CSEEFUNC(bap_csee,
		 !(map->sensorflags & (1 << SENSOR_BAP)) &&
		 !AnyECMDisturbed(m) &&
		 t &&
		 !AngelECMProtected(t) &&
		 !StealthArmorActive(t) && !NullSigSysActive(t));

/* Bloodhound is only disrupted by ECM. */
CSEEFUNC(blood_csee,
		 !(map->sensorflags & (1 << SENSOR_BHAP)) &&
		 !AnyECMDisturbed(m) && t && !AngelECMProtected(t));

/* Basically, mechs w/o heat are +2 tohit, mechs in utter overheat are
   -2 tohit */
#ifdef BT_SCALED_INFRARED
#define HEAT_MODIFIER(a) ((a) <= 0 ? 2 : (a) > 50 ? -2 : (a) > 35 ? -1 : (a) > 20 ? 0 : 1)
#else

/*
#define HEAT_MODIFIER(a) ((a) <= 7 ? 2 : (a) > 28 ? -2 : (a) > 21 ? -1 : (a) > 14 ? 0 : 1)
*/

#define HEAT_MODIFIER(a) ((a) <= 7 ? 2 : (a) <= 10 ? 1 : (a) <= 15 ? 0 : (a) <= 22 ? -1 : -2)
#endif
/* Heavy/assault -1 tohit, medium 0, light +1 */
#define WEIGHT_MODIFIER(a) (a > 65 ? -1 : a > 35 ? 0 : 1)

/* If target's moving, +1 tohit */
#define MOVE_MODIFIER(a) (abs(a) >= 10.75 ? 1 : 0)

#define nwood_count(mech,a)  (MechLOSFlag_WoodCount(a) + \
                             ((MechElevation(mech) + 2) < MechZ(mech) ? 0 : \
			      MechRTerrain(mech) == LIGHT_FOREST ? 1 : \
			      MechRTerrain(mech) == HEAVY_FOREST ? 2 : 0))

/* To-hit functions */
/* Visual - Non-Day, Interrupting woods, partial LOS, and hulldown. */
TOHITFUNC(vislight_tohit, ((!t ||
							!IsLit(t)) ? (2 - l) : 0) + nwood_count(t,
																	f) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 3 + (IsHulldown(t) ? 2 : 0) : 0));

/* Liteamp - Interrupting woods, partial LOS, hulldown. */
TOHITFUNC(liteamp_tohit, ((2 - l) / 2) + ((nwood_count(t,
													   f) * 3) / 2) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 3 + (IsHulldown(t) ? 2 : 0) : 0));

/* Infrared - Interrupting Woods, partial LOS, Hulldown, heat. */
#ifdef BT_SCALED_INFRARED
TOHITFUNC(infrared_tohit, ((nwood_count(t, f) * 4) / 3) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 3 : 0) +
		  HEAT_MODIFIER((2 * (MechPlusHeat(t) - MechMinusHeat(t))) +
						MIN(MechPlusHeat(t), MechMinusHeat(t))));
#else
TOHITFUNC(infrared_tohit, ((nwood_count(t,
										f) * 4) / 3) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 3 + (IsHulldown(t) ? 2 : 0) : 0) +
		  HEAT_MODIFIER(MechHeat(t) + 7));
#endif
/* Emag - Interrupting woods, partial LOS, hulldwon, weight/movement,
 * recently fired. */
TOHITFUNC(electrom_tohit, ((nwood_count(t,
										f) * 2) / 3) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 3 + (IsHulldown(t) ? 2 : 0) : 0) +
		  WEIGHT_MODIFIER(MechTons(t)) + MOVE_MODIFIER(MechSpeed(t)) +
		  (MechStatus(t) & FIRED ? -1 : 0) + MNumber(m, 0, 1));

/* Seismic - Partial LOS, hulldown, weight, speed */
TOHITFUNC(seismic_tohit,
		  2 + ((f & MECHLOSFLAG_PARTIAL) ? 3 + (IsHulldown(t) ? 2 : 0) : 0) +
		  WEIGHT_MODIFIER(MechRealTons(t)) - MOVE_MODIFIER(MechSpeed(t)) +
		  MNumber(m, 0, 1));

/* BAP - Flat BTH? */
TOHITFUNC(bap_tohit, MNumber(m, 0, 2));	/* Very evil */

/* BloodHound - Flat BTH? */
TOHITFUNC(blood_tohit, MNumber(m, 0, 2));	/* Very evil */

/* Radar - Only 10z and above, partial LOS, interrupting woods. */
TOHITFUNC(radar_tohit, ((MechZ(t) >= 10 ||
						 FlyingT(t)) ? -3 : 0) +
		  ((f & MECHLOSFLAG_PARTIAL) ? 2 + (IsHulldown(t) ? 2 : 0) : 0) +
		  nwood_count(t, f));