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.ecm.c,v 1.2 2005/06/23 18:31:42 av1-op Exp $
 *
 * Author: Markus Stenberg <fingon@iki.fi>
 *
 *  Copyright (c) 1997 Markus Stenberg
 *  Copyright (c) 1998-2002 Thomas Wouters
 *  Copyright (c) 2000-2002 Cord Awtry
 *       All rights reserved
 *
 * Created: Fri Mar 21 15:13:06 1997 fingon
 * Last modified: Sat Oct 25 18:03:03 1997 fingon
 *
 */

#include "mech.h"
#include "p.mech.utils.h"
#include "mech.ecm.h"

	/*
	 * This is a rewrite of the ECM code to support ECCM. I've redone everything
	 * so that multiple ECM/ECCM units can operate and gain the advantage in numbers
	 *
	 * Mar.10.2001
	 * Kipsta
	 */

#define LOUD_ECM				/* No complete stealth */
#undef VERY_LOUD_ECM			/* But no spam, either */

void sendECMNotification(MECH * objMech, int wMsgType)
{
	switch (wMsgType) {
	case ECM_NOTIFY_DISTURBED:

#ifdef LOUD_ECM
		mech_notify(objMech, MECHALL,
					"Half your screens are suddenly filled with static!");

#ifdef VERY_LOUD_ECM
		if(MechSpecials(objMech) & BEAGLE_PROBE_TECH &&
		   !(MechCritStatus(objMech) & BEAGLE_DESTROYED))
			mech_notify(objMech, MECHALL,
						"Your Beagle Active Probe is inoperative!");
		if(MechSpecials2(objMech) & BLOODHOUND_PROBE_TECH &&
		   !(MechCritStatus(objMech) & BLOODHOUND_DESTROYED))
			mech_notify(objMech, MECHALL,
						"Your Bloodhound Active Probe is inoperative!");
		if(IsC3(objMech))
			mech_notify(objMech, MECHALL, "Your C3 network is inoperative!");
		if(IsC3i(objMech))
			mech_notify(objMech, MECHALL, "Your C3i network is inoperative!");

#endif /*  */
#endif /*  */
		break;
	case ECM_NOTIFY_UNDISTURBED:

#ifdef LOUD_ECM
		mech_notify(objMech, MECHALL,
					"All your systems are back to normal again!");

#ifdef VERY_LOUD_ECM
		if(MechSpecials(objMech) & BEAGLE_PROBE_TECH &&
		   !(MechCritStatus(objMech) & BEAGLE_DESTROYED))
			mech_notify(objMech, MECHALL,
						"Your Beagle Active Probe is operational again!");
		if(MechSpecials2(objMech) & BLOODHOUND_PROBE_TECH &&
		   !(MechCritStatus(objMech) & BLOODHOUND_DESTROYED))
			mech_notify(objMech, MECHALL,
						"Your Bloodhound Active Probe is operational again!");
		if(IsC3(objMech))
			mech_notify(objMech, MECHALL,
						"Your C3 network is operational again!");
		if(IsC3i(objMech))
			mech_notify(objMech, MECHALL,
						"Your C3i network is operational again!");

#endif /*  */
#endif /*  */
		break;
	case ECM_NOTIFY_COUNTERED:
		if(HasWorkingECMSuite(objMech))
			mech_notify(objMech, MECHALL,
						"Your ECM suite's ready light turns red, countered by enemy ECCM!");
		break;
	case ECM_NOTIFY_UNCOUNTERED:
		if(HasWorkingECMSuite(objMech))
			mech_notify(objMech, MECHALL,
						"Your ECM suite's ready light turns green, enemy ECCM is out of range.");
		break;
	}
}
void checkECM(MECH * objMech)
{
	MAP *objMapmap;
	MECH *objOtherMech;
	float range = 0.0;

	int wFriendlyECM = 0;
	int wFriendlyECCM = 0;
	int wUnFriendlyECM = 0;
	int wUnFriendlyECCM = 0;

	int wFriendlyAngelECM = 0;
	int wFriendlyAngelECCM = 0;
	int wUnFriendlyAngelECM = 0;
	int wUnFriendlyAngelECCM = 0;

	int wFriendlyECMDelta = 0;
	int wFriendlyECCMDelta = 0;

	int tCheckECM = 0;
	int tCheckECCM = 0;

	int wIter = 0;
	int tMark = 0;

	if(!(objMapmap = FindObjectsData(objMech->mapindex)))	/* get our map */
		return;

	for(wIter = 0; wIter < objMapmap->first_free; wIter++) {
		if(!(objOtherMech = FindObjectsData(objMapmap->mechsOnMap[wIter])))
			continue;

		if((range = FaMechRange(objOtherMech, objMech)) > ECM_RANGE)
			continue;

		if(MechTeam(objOtherMech) == MechTeam(objMech)) {
			if(ECMEnabled(objOtherMech))
				wFriendlyECM++;

			if(ECCMEnabled(objOtherMech))
				wFriendlyECCM++;

			if(AngelECMEnabled(objOtherMech))
				wFriendlyAngelECM++;

			if(AngelECCMEnabled(objOtherMech))
				wFriendlyAngelECCM++;

			if(range <= 0.5) {
				if(PerECMEnabled(objOtherMech))
					wFriendlyECM++;

				if(PerECCMEnabled(objOtherMech))
					wFriendlyECCM++;
			}
		} else {
			if(ECMEnabled(objOtherMech))
				wUnFriendlyECM++;

			if(ECCMEnabled(objOtherMech))
				wUnFriendlyECCM++;

			if(AngelECMEnabled(objOtherMech))
				wUnFriendlyAngelECM++;

			if(AngelECCMEnabled(objOtherMech))
				wUnFriendlyAngelECCM++;

			if(range <= 0.5) {
				if(PerECMEnabled(objOtherMech))
					wUnFriendlyECM++;

				if(PerECCMEnabled(objOtherMech))
					wUnFriendlyECCM++;
			}
		}
	}

	if((MechStatus2(objMech) & STH_ARMOR_ON) ||
	   checkAllSections(objMech, INARC_ECM_ATTACHED))
		wUnFriendlyECM += 1000;

	/* Generate our deltas */
	wFriendlyECMDelta =
		wFriendlyECM + (2 * wFriendlyAngelECM) - wUnFriendlyECCM -
		(2 * wUnFriendlyAngelECCM);
	wFriendlyECCMDelta =
		wFriendlyECCM + (2 * wFriendlyAngelECCM) - wUnFriendlyECM -
		(2 * wUnFriendlyAngelECM);

	tCheckECM = ((wFriendlyECM != 0) || (wFriendlyAngelECM != 0) ||
				 (wUnFriendlyECCM != 0) || (wUnFriendlyAngelECCM != 0));
	tCheckECCM = ((wFriendlyECCM != 0) || (wFriendlyAngelECCM != 0) ||
				  (wUnFriendlyECM != 0) || (wUnFriendlyAngelECM != 0));

	/* SendDebug(tprintf("Checking unit %d. ECMDelta: %d. ECCMDelta: %d. CheckECM: %d. CheckECCM: %d",objMech->mynum,wFriendlyECMDelta,wFriendlyECCMDelta,tCheckECM,tCheckECCM)); */

	/* Now we do our checks... */
	/* Let's first see if we should just reset our flags... 'cause there's no ECM or ECCM around */
	if(!tCheckECM) {
		if(ECMCountered(objMech)) {
			sendECMNotification(objMech, ECM_NOTIFY_UNCOUNTERED);
			UnSetECMCountered(objMech);
			tMark = 1;
		}

		if(ECMProtected(objMech) || AngelECMProtected(objMech)) {
			UnSetECMProtected(objMech);
			UnSetAngelECMProtected(objMech);
			tMark = 1;
		}
	}

	if(!tCheckECCM) {
		if(AnyECMDisturbed(objMech)) {
			sendECMNotification(objMech, ECM_NOTIFY_UNDISTURBED);
			UnSetECMDisturbed(objMech);
			UnSetAngelECMDisturbed(objMech);
			tMark = 1;
		}
	}

	/* Sanity check so we don't bother to do all the other checks */
	if(!tCheckECM && !tCheckECCM) {
		if(tMark)
			MarkForLOSUpdate(objMech);

		return;
	}

	/* Now we see if our ECM has been countered */
	if(tCheckECM) {
		if(wFriendlyECMDelta <= 0) {	/* They have the same or more ECCM than we have ECM */
			if(!ECMCountered(objMech)) {
				sendECMNotification(objMech, ECM_NOTIFY_COUNTERED);
				SetECMCountered(objMech);
				UnSetECMProtected(objMech);
				UnSetAngelECMProtected(objMech);
			}
		} else {
			if(ECMCountered(objMech)) {
				sendECMNotification(objMech, ECM_NOTIFY_UNCOUNTERED);
				UnSetECMCountered(objMech);
			}

			if(wFriendlyECM > 0)
				SetECMProtected(objMech);
			else
				UnSetECMProtected(objMech);

			if(wFriendlyAngelECM > 0)
				SetAngelECMProtected(objMech);
			else
				UnSetAngelECMProtected(objMech);
		}
	}

	/* Now we see if we're under an enemy ECM umbrella */
	if(tCheckECCM) {
		if(wFriendlyECCMDelta < 0) {	/* They have more ECM than we have ECCM */
			if(!AnyECMDisturbed(objMech)) {
				sendECMNotification(objMech, ECM_NOTIFY_DISTURBED);

				if(wUnFriendlyECM > 0)
					SetECMDisturbed(objMech);
				else
					UnSetECMDisturbed(objMech);

				if(wUnFriendlyAngelECM > 0)
					SetAngelECMDisturbed(objMech);
				else
					UnSetAngelECMDisturbed(objMech);

				MarkForLOSUpdate(objMech);
			}
		} else {
			if(AnyECMDisturbed(objMech)) {
				sendECMNotification(objMech, ECM_NOTIFY_UNDISTURBED);

				UnSetECMDisturbed(objMech);
				UnSetAngelECMDisturbed(objMech);
				MarkForLOSUpdate(objMech);
			}
		}
	}
}

/* mech_ecm moved to mech.advanced.c */