Ejemplo n.º 1
0
void AreaTrigger::Update(uint32 diff)
{
    WorldObject::Update(diff);
    _timeSinceCreated += diff;

    // "If" order matter here, Circular Movement > Attached > Splines
    if (HasCircularMovement())
    {
        UpdateCircularMovementPosition(diff);
    }
    else if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_ATTACHED))
    {
        if (Unit* target = GetTarget())
            GetMap()->AreaTriggerRelocation(this, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
    }
    else
        UpdateSplinePosition(diff);

    if (GetDuration() != -1)
    {
        if (GetDuration() > int32(diff))
            _UpdateDuration(_duration - diff);
        else
        {
            Remove(); // expired
            return;
        }
    }

    _ai->OnUpdate(diff);

    UpdateTargetList();
}
Ejemplo n.º 2
0
void MissileClass::RunSeeker(){	
	SimObjectType *lockedTarget;

	// Don't come here without a sensor
	// Shouldn't be necessary, but at this stage, lets be safe...
	// No seeker if in SAFE
	if (
		!sensorArray || !sensorArray[0] ||
		launchState == PreLaunch && parent && parent->IsAirplane() &&
		((AircraftClass*)parent.get())->Sms->MasterArm() == SMSBaseClass::Safe
	){
		return;
	}

	// START_PROFILE("SEEKERS");
	// TODO:  This seems to do extra work to generate a matrix (vmat).
	// would it be worth a special CalcRelGeom call that avoids this???
	if (launchState == InFlight){
		if (targetPtr){
			// we have a target
			CalcRelGeom(this, targetPtr, NULL, 1.0F / SimLibMajorFrameTime);
		}
		else {	
			// we dont have a target, create/update the target list
			targetList = UpdateTargetList(targetList, this, SimDriver.combinedList);
			CalcRelGeom(this, targetList, NULL, 1.0F / SimLibMajorFrameTime);
		}
	}

	// see if its time to go active
	float factor = ((targetPtr && targetPtr->BaseData()->IsSPJamming()) ? 1.5f : 1.0f);
	if (
		inputData->mslActiveTtg > 0 && 
		(
			timpct * factor < inputData->mslActiveTtg && 
			sensorArray[0]->Type() != SensorClass::Radar
		) || 
		(
			launchState == InFlight && sensorArray[0]->Type() != SensorClass::Radar && 
			(!isSlave || !targetPtr) //I-Hawk - was missing the parentheses here, caused heat seeker locking problems
		)
	){
		GoActive();
		// sfr shouldnt we finish here?
	}	

	// exec the sensor and get locked target
	lockedTarget = sensorArray[0]->Exec(targetList);

	// Make sure we don't target ourselves
	if (lockedTarget && lockedTarget->BaseData() == parent){
		lockedTarget = NULL;
	}
	
	// Deal with the case where the seeker lost lock on the intended target
	if (lockedTarget != targetPtr){
		if (
			(inputData->mslActiveTtg > 0) && 
			(sensorArray[0]->Type() != SensorClass::Radar) && 
			launchState == InFlight
		){
			// We can switch from passive to active guidance - go active if passive fails
			GoActive();
			// sfr: shouldnt we finish here
		}
		else if (targetPtr && targetPtr->localData->range*targetPtr->localData->range <= lethalRadiusSqrd){
			// We were close enough to detonate, so do it
			flags |= ClosestApprch;
		}
		else {
			// Record that we lost lock on our original target
			flags |= SensorLostLock;
			
			// Update relative geometry on the new target (if any)
			if (lockedTarget){
				SimObjectType* newNext = lockedTarget->next;
				lockedTarget->next = NULL;
				CalcRelGeom(this, lockedTarget, NULL, 1.0F / SimLibMajorFrameTime);
				lockedTarget->next = newNext;
			}
			// 2000-08-31 ADDED BY S.G. WHEN LOCK LOST, HAVE THE MISSILE SEEKER POINT WHERE IT WAS LAST SEEN
			else if (targetPtr){
				SetRdrAzCenter(targetPtr->localData->az);
				SetRdrElCenter(targetPtr->localData->el);
			}
			else {
				SetRdrAzCenter(0.0f);
				SetRdrElCenter(0.0f);
			}
			// END OF ADDED SECTION			
			// Take the new target
			SetTarget(lockedTarget);
		}
	}
	//STOP_PROFILE("SEEKERS");
}
Ejemplo n.º 3
0
void MissileClass::RunSeeker()
{	
	// COBRA - RED - To dentify locally created target lists
	bool localList = false;

	SimObjectType *newTarget = targetPtr, *lockedTarget=NULL;

	// Don't come here without a sensor
	ShiAssert( sensorArray );
	if ( !sensorArray ) return;		// Shouldn't be necessary, but at this stage, lets be safe...

	// Don't come here without a sensor
	ShiAssert( sensorArray[0] );
	if ( !sensorArray[0] ) return;		// Shouldn't be necessary, but at this stage, lets be safe...

	// No seeker if in SAFE
	if (
	   launchState == PreLaunch && parent && parent->IsAirplane() &&
       ((AircraftClass*)parent.get())->Sms->MasterArm() == SMSBaseClass::Safe
	){
		return;
	}

	// START_PROFILE("SEEKERS");
	// TODO:  This seems to do extra work to generate a matrix (vmat).
	// would it be worth a special CalcRelGeom call that avoids this???
	if (launchState == InFlight){
		if (targetPtr){
			CalcRelGeom(this, targetPtr, NULL, 1.0F / SimLibMajorFrameTime);
		}
		else {	
			// COBRA - RED - OK, We r creating a local list
			localList = true;
			newTarget = UpdateTargetList(NULL, this, SimDriver.combinedList);
			CalcRelGeom(this, newTarget, NULL, 1.0F / SimLibMajorFrameTime);
		}
	}

	// For missiles that go active (AMRAAM) is it time to switch seekers?
	ShiAssert( timpct >= 0.0f );	// If this fails, we might try to give ANY missile an active radar
	// KLUDGE: 2000-08-26 MODIFIED BY S.G. SO ARH MISSILE WAIT LONGER WHEN THE TARGET IS JAMMING
	// IT DOESN'T MATTER IF targetPtr IS NULL AND newTarget IS SET BECAUSE GoActive 
	// WILL BE DONE LATER IN THE	ROUTINE ANYHOW IN SUCH A SCENARIO
	//	if ((timpct < inputData->mslActiveTtg) && (sensorArray[0]->Type() != SensorClass::Radar))

	// ME123 WE GET A CTD HERE IF NOT MAKING THE ARH CHECK FIRST !
	//	if (timpct * 
	// ((targetPtr && targetPtr->BaseData()->IsSPJamming()) ? 1.5f : 1.0f) < 
	// inputData->mslActiveTtg && sensorArray[0]->Type() != SensorClass::Radar)
	// Marco edit - Also added in GoActive for 'Mad Dog' Launches
	//if (
	//	inputData->mslActiveTtg > 0 && 
	//	launchState == InFlight && 
	//	sensorArray[0]->Type() != SensorClass::Radar && 
	//	!isSlave
	//){
	//	Pitbull = false;
	//}

	float factor = ((targetPtr && targetPtr->BaseData()->IsSPJamming()) ? 1.5f : 1.0f);
	if (
		inputData->mslActiveTtg > 0 && 
		(
			timpct * factor < inputData->mslActiveTtg && 
			sensorArray[0]->Type() != SensorClass::Radar
		) || 
		(
			inputData->mslActiveTtg > 0 && 
			launchState == InFlight && sensorArray[0]->Type() != SensorClass::Radar && 
			(!isSlave || !targetPtr)
		)
	){
		GoActive();
	}
	

	// COBRA - RED - The memory Leakage Correction 
	// **************************************** OLD CODE *****************************
	// newTarget = sensorArray[0]->Exec( newTarget );
	// ************************************* END OLD CODE ****************************
	// Exec the seeker
	// **************************************** NEW CODE *****************************
	// We r getting the locked target in a new variable avoiding loosing the target list
	// reference if the ssensor is not locked ( Exec() returns NULL )
	lockedTarget = sensorArray[0]->Exec( newTarget );
	// if NO LOCK and the list is created on flight ( i.e. Not the FCC List ), the created list is deleted
	// for such purpose I created ReleaseTargetList() function in 'simObj.cpp'
	// sfr: this prolly fix leak
#define ALWAYS_RELEASE_LOCAL_LIST 1
#if ALWAYS_RELEASE_LOCAL_LIST
	if (localList/* && (!lockedTarget)*/) {
		ReleaseTargetList(newTarget);
		targetPtr=NULL;
	}
#else
	if (localList && (!lockedTarget)){
		ReleaseTargetList(newTarget);
		targetPtr=NULL;
	}
#endif
	// Finally, the new Target is updated with whatever is locked by sensor
	newTarget = lockedTarget;
	// ********************************** NEW CODE - END *****************************

	// Make sure we don't target ourselves
	if (newTarget && newTarget->BaseData() == parent){
#if ALWAYS_RELEASE_LOCAL_LIST
		// sfr: should we release targets??
		ReleaseTargetList(newTarget);
#endif
		newTarget = NULL;
	}
	
	// Deal with the case where the seeker lost lock on the intended target
	if (newTarget != targetPtr){
		if (
			(inputData->mslActiveTtg > 0) && 
			(sensorArray[0]->Type() != SensorClass::Radar) && 
			launchState == InFlight
		){
			// We can switch from passive to active guidance - go active if passive fails
			GoActive();
		}
		else if (targetPtr && targetPtr->localData->range*targetPtr->localData->range <= lethalRadiusSqrd){
			// We were close enough to detonate, so do it
			flags |= ClosestApprch;
		}
		else {
			// Record that we lost lock on our original target
			flags |= SensorLostLock;
			
			// Update relative geometry on the new target (if any)
			if (newTarget){
				SimObjectType* newNext = newTarget->next;
				newTarget->next = NULL;
				CalcRelGeom(this, newTarget, NULL, 1.0F / SimLibMajorFrameTime);
				newTarget->next = newNext;
			}
			// 2000-08-31 ADDED BY S.G. WHEN LOCK LOST, HAVE THE MISSILE SEEKER POINT WHERE IT WAS LAST SEEN
			else if (targetPtr){
				SetRdrAzCenter(targetPtr->localData->az);
				SetRdrElCenter(targetPtr->localData->el);
			}
			else {
				SetRdrAzCenter(0.0f);
				SetRdrElCenter(0.0f);
			}
			// END OF ADDED SECTION			
			// Take the new target
			SetTarget(newTarget);
		}
	}


	// TODO:  Kill this.  Only used by LimitSeeker below
	// sfr: ok, killed.
#if 0
	if (targetPtr) {
		//me123 check if the missile seekerhead can track
		//SetSeekerPos(&targetPtr->localData->az,&targetPtr->localData->el);
		ata = targetPtr->localData->ata;
		if (
			ata > inputData->gimlim ||
			fabs( sensorArray[0]->SeekerAz() - targetPtr->localData->az) >inputData->atamax||
			fabs( sensorArray[0]->SeekerEl() - targetPtr->localData->el) >inputData->atamax
		){
			//flags |= SensorLostLock;
			//SetTarget( NULL );
		}
	}
#endif
	//STOP_PROFILE("SEEKERS");
}