/* * $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 */