Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
// Purpose: Override base class to add display of paths
//-----------------------------------------------------------------------------
void CScriptedTarget::DrawDebugGeometryOverlays(void) 
{
	// ----------------------------------------------
	// Draw line to next target is bbox is selected
	// ----------------------------------------------
	if (m_debugOverlays & (OVERLAY_BBOX_BIT|OVERLAY_ABSBOX_BIT))
	{
		if (m_iDisabled)
		{
			NDebugOverlay::Box(GetAbsOrigin(), Vector(-5,-5,-5), Vector(5,5,5), 200,100,100, 0 ,0);
		}
		else
		{
			NDebugOverlay::Cross3D(m_vLastPosition,	Vector(-8,-8,-8),Vector(8,8,8),255,0,0,true,0.1);
			NDebugOverlay::Box(GetAbsOrigin(), Vector(-5,-5,-5), Vector(5,5,5), 255,0,0, 0 ,0);
			NDebugOverlay::Line(GetAbsOrigin(),m_vLastPosition,255,0,0,true,0.0);
		}

		CBaseEntity *pTarget = GetNextTarget();
		if (pTarget)
		{
			NDebugOverlay::Line(GetAbsOrigin(),pTarget->GetAbsOrigin(),200,100,100,true,0.0);
		}
		if (GetTarget() != NULL)
		{
			NDebugOverlay::Line(GetAbsOrigin(),GetTarget()->EyePosition(),0,255,0,true,0.0);
		}

	}
	CBaseEntity::DrawDebugGeometryOverlays();
}
Ejemplo n.º 2
0
bool CFuncLadderEndPoint::Validate()
{
	// Find the the other end
	Vector startPos = GetAbsOrigin();
	
	CFuncLadderEndPoint *other = dynamic_cast< CFuncLadderEndPoint * >( GetNextTarget() );
	if ( !other )
	{
		DevMsg( 1, "func_ladderendpoint(%s) without matching target\n", STRING(GetEntityName()) );
		return false;
	}

	Vector endPos = other->GetAbsOrigin();

	CFuncLadder *ladder = ( CFuncLadder * )CreateEntityByName( "func_useableladder" );
	if ( ladder )
	{
		ladder->SetEndPoints( startPos, endPos );
		ladder->SetAbsOrigin( GetAbsOrigin() );
		ladder->SetParent( GetParent() );
		ladder->SetName( GetEntityName() );
		ladder->Spawn();
	}

	// Delete both endpoints
	UTIL_Remove( other );
	UTIL_Remove( this );

	return true;
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CPointTeleport::Activate( void )
{
	CBaseEntity *pTarget = GetNextTarget();
	if (pTarget)
	{
		if ( pTarget->GetMoveParent() != NULL )
		{
			Warning("ERROR: (%s) can't teleport object (%s) as it has a parent!\n",GetDebugName(),pTarget->GetDebugName());

			return;
		}
		if (m_spawnflags & SF_TELEPORT_TO_SPAWN_POS)
		{
			m_vSaveOrigin = pTarget->GetAbsOrigin();
			m_vSaveAngles = pTarget->GetAbsAngles();
		}
		else
		{
			m_vSaveOrigin = GetAbsOrigin();
			m_vSaveAngles = GetAbsAngles();
		}
	}
	else
	{
		Warning("ERROR: (%s) given no target.  Deleting.\n",GetDebugName());
		UTIL_Remove(this);
		return;
	}
	BaseClass::Activate();
}
Ejemplo n.º 4
0
//
// Train next - path corner needs to change to next target 
//
void CFuncTrain::Next( void )
{
	CBaseEntity	*pTarg;


	// now find our next target
	//TODO: this entity is supposed to work with path_corner only. Other entities will work, but will probably misbehave. - Solokiller
	//Check for classname and ignore others?
	pTarg = GetNextTarget();

	if( !pTarg )
	{
		if( pev->noiseMovement )
			STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ) );
		// Play stop sound
		if( pev->noiseStopMoving )
			EMIT_SOUND( this, CHAN_VOICE, ( char* ) STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM );
		return;
	}

	// Save last target in case we need to find it again
	pev->message = pev->target;

	pev->target = pTarg->pev->target;
	m_flWait = pTarg->GetDelay();

	if( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 )
	{// don't copy speed from target if it is 0 (uninitialized)
		pev->speed = m_pevCurrentTarget->speed;
		ALERT( at_aiconsole, "Train %s speed to %4.2f\n", GetTargetname(), pev->speed );
	}
	m_pevCurrentTarget = pTarg->pev;// keep track of this since path corners change our target for us.

	pev->enemy = pTarg->edict();//hack

	if( FBitSet( m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT ) )
	{
		// Path corner has indicated a teleport to the next corner.
		SetBits( pev->effects, EF_NOINTERP );
		SetAbsOrigin( pTarg->GetAbsOrigin() - ( pev->mins + pev->maxs )* 0.5 );
		Wait(); // Get on with doing the next path corner.
	}
	else
	{
		// Normal linear move.

		// CHANGED this from CHAN_VOICE to CHAN_STATIC around OEM beta time because trains should
		// use CHAN_STATIC for their movement sounds to prevent sound field problems.
		// this is not a hack or temporary fix, this is how things should be. (sjb).
		if( pev->noiseMovement )
		{
			STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ) );
			EMIT_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ), m_volume, ATTN_NORM );
		}
		ClearBits( pev->effects, EF_NOINTERP );
		SetMoveDone( &CFuncTrain::Wait );
		LinearMove( pTarg->GetAbsOrigin() - ( pev->mins + pev->maxs )* 0.5, pev->speed );
	}
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
// Purpose: Draw any debug text overlays
// Output : Current text offset from the top
//-----------------------------------------------------------------------------
int CScriptedTarget::DrawDebugTextOverlays(void) 
{
	// Skip AIClass debug overlays
	int text_offset = CBaseEntity::DrawDebugTextOverlays();

	if (m_debugOverlays & OVERLAY_TEXT_BIT) 
	{
		// --------------
		// Print State
		// --------------
		char tempstr[512];
		if (m_iDisabled) 
		{
			Q_strncpy(tempstr,"State: Off",sizeof(tempstr));
		}
		else
		{
			Q_strncpy(tempstr,"State: On",sizeof(tempstr));
		}
		EntityText(text_offset,tempstr,0);
		text_offset++;

		// -----------------
		// Print Next Entity
		// -----------------
		CBaseEntity *pTarget = GetNextTarget();
		if (pTarget) 
		{
			Q_snprintf(tempstr,sizeof(tempstr),"Next: %s",pTarget->GetDebugName() );
		}
		else
		{
			Q_strncpy(tempstr,"Next: -NONE-",sizeof(tempstr));
		}
		EntityText(text_offset,tempstr,0);
		text_offset++;

		// --------------
		// Print Target
		// --------------
		if (GetTarget()!=NULL) 
		{
			Q_snprintf(tempstr,sizeof(tempstr),"User: %s",GetTarget()->GetDebugName() );
		}
		else if (m_iDisabled)
		{
			Q_strncpy(tempstr,"User: -NONE-",sizeof(tempstr));
		}
		else 
		{
			Q_strncpy(tempstr,"User: -LOOKING-",sizeof(tempstr));
		}
		EntityText(text_offset,tempstr,0);
		text_offset++;
	}
	return text_offset;
}
Ejemplo n.º 6
0
void CGunTarget::Start( void )
{
	m_takedamage = DAMAGE_YES;
	AddFlag( FL_AIMTARGET );
	m_hTargetEnt = GetNextTarget();
	if ( m_hTargetEnt == NULL )
		return;
	m_iHealth = m_iMaxHealth;
	Next();
}
Ejemplo n.º 7
0
void CGunTarget::Activate( void )
{
	CBaseEntity	*pTarg;

	// now find our next target
	pTarg = GetNextTarget();
	if( pTarg )
	{
		m_hTargetEnt = pTarg;
		UTIL_SetOrigin( pev, pTarg->pev->origin - ( pev->mins + pev->maxs ) * 0.5 );
	}
}
Ejemplo n.º 8
0
void CGunTarget::Activate( void )
{
	BaseClass::Activate();

	CBaseEntity	*pTarg;
	// now find our next target
	pTarg = GetNextTarget();
	if ( pTarg )
	{
		m_hTargetEnt = pTarg;
		Vector nextPos = pTarg->GetAbsOrigin();
		Teleport( &nextPos, NULL, NULL );
	}
}
Ejemplo n.º 9
0
void CGunTarget::Next( void )
{
	SetThink( NULL );

	m_hTargetEnt = GetNextTarget();
	CBaseEntity *pTarget = m_hTargetEnt;

	if( !pTarget )
	{
		Stop();
		return;
	}
	SetMoveDone( &CGunTarget::Wait );
	LinearMove( pTarget->pev->origin - ( pev->mins + pev->maxs ) * 0.5, pev->speed );
}
Ejemplo n.º 10
0
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
void CPointTeleport::InputTeleport( inputdata_t &inputdata )
{
	CBaseEntity *pTarget = GetNextTarget();
	if (pTarget)
	{
		// If teleport object is in a movement hierarchy, remove it first
		if ( pTarget->GetMoveParent() != NULL )
		{
			Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName());
			return;
		}

		pTarget->Teleport( &m_vSaveOrigin, &m_vSaveAngles, NULL );
	}
}
Ejemplo n.º 11
0
	void CActionDungeonSwitchOn::DoAction()
	{
		const WORD switchNum = (WORD)GetValue(eProperty_Dungeon_SwitchOn);
		if(0 == switchNum)
			return;

		// 해당 스위치가 On상태이면 처리할 필요가 없으므로 종료시킨다.
		int switchState = DungeonMGR->GetSwitch(GetChannelID(), switchNum - 1);
		if( 0 != switchState )
			return;

		DungeonMGR->SetSwitch(GetChannelID(), switchNum - 1, TRUE);

		// 스위치로 NPC를 사용할 경우, 이펙트를 표시하여 스위치 On/Off를 표현한다.
		const WORD dwNpcIndex = (WORD)GetValue(eProperty_ActiveNpcId);
		if( 0 == dwNpcIndex || GetValue(eProperty_ObjectKind) != eObjectKind_Npc)
			return;
		
        const DWORD dwObjectIndex = DungeonMGR->GetNpcObjectIndex(GetChannelID(), dwNpcIndex);
		if( 0 == dwObjectIndex )
			return;

		const WORD wEffectIndex = (WORD)GetValue(eProperty_EffectDescNum);

		for(DWORD objectIndex = GetHeadTarget();
			objectIndex > 0;
			objectIndex = GetNextTarget())
		{
			CObject* const object = g_pUserTable->FindUser(objectIndex);

			if(0 == object)
			{
				continue;
			}
			MSG_DWORD5	msg;
			msg.Category = MP_TRIGGER;
			msg.Protocol = MP_TRIGGER_ADDEFFECT_ACK;
			msg.dwObjectID = dwObjectIndex;
			msg.dwData1 = wEffectIndex;
			msg.dwData2 = GetValue(eProperty_EffectAddToMap);
			msg.dwData3 = GetValue(eProperty_PosX);
			msg.dwData4 = GetValue(eProperty_PosY);
			msg.dwData5 = GetValue(eProperty_PosZ);

			PACKEDDATA_OBJ->QuickSend( object, &msg, sizeof( msg ) );
		}
		return ;
	}
Ejemplo n.º 12
0
void CGunTarget::Next( void )
{
	SetThink( NULL );

	m_hTargetEnt = GetNextTarget();
	CBaseEntity *pTarget = m_hTargetEnt;
	
	if ( !pTarget )
	{
		Stop();
		return;
	}

	SetMoveDone( &CGunTarget::Wait );
	LinearMove( pTarget->GetLocalOrigin(), m_flSpeed );
}
Ejemplo n.º 13
0
	void CActionEngineEffect::DoAction()
	{
		const DWORD hashCode = GetValue(eProperty_Name);
		const DWORD positionX = GetValue(eProperty_PosX);
		const DWORD positionZ = GetValue(eProperty_PosZ);		
		const DWORD motionIndex = GetValue(eProperty_Value);
		const DWORD angle = GetValue(eProperty_Angle);
		const DWORD isLoop = GetValue(eProperty_Loop);

		MSG_NAME_DWORD5 message;
		ZeroMemory(
			&message,
			sizeof(message));
		message.Category = MP_TRIGGER;
		message.Protocol = MP_TRIGGER_ENGINE_EFFECT_ACK;
		message.dwData1 = positionX;
		message.dwData2 = positionZ;
		message.dwData3 = motionIndex;
		message.dwData4 = angle;
		message.dwData5 = isLoop;
		SafeStrCpy(
			message.Name,
			GetAliasName(hashCode),
			sizeof(message.Name) / sizeof(*message.Name));
		
		for(DWORD objectIndex = GetHeadTarget();
			objectIndex > 0;
			objectIndex = GetNextTarget())
		{
			CObject* const object = g_pUserTable->FindUser(objectIndex);

			if(0 == object)
			{
				continue;
			}
			else if(eObjectKind_Player != object->GetObjectKind())
			{
				continue;
			}
		
			object->SendMsg(
				&message,
				sizeof(message));
		}
	}
Ejemplo n.º 14
0
void CGunTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if( !ShouldToggle( useType, m_on ) )
		return;

	if( m_on )
	{
		Stop();
	}
	else
	{
		//TODO: m_on is never turned on here. - Solokiller
		pev->takedamage = DAMAGE_AIM;
		m_hTargetEnt = GetNextTarget();
		if( m_hTargetEnt == NULL )
			return;
		pev->health = pev->max_health;
		Next();
	}
}
Ejemplo n.º 15
0
	void CActionKillMonster::DoAction()
	{
		for(DWORD objectIndex = GetHeadTarget();
			objectIndex > 0;
			objectIndex = GetNextTarget())
		{
			CObject* const object = g_pUserTable->FindUser(objectIndex);

			if(0 == object)
			{
				continue;
			}
			else if(FALSE == (object->GetObjectKind() & eObjectKind_Monster))
			{
				continue;
			}

			g_pServerSystem->RemoveMonster(object->GetID());
		}
	}
Ejemplo n.º 16
0
void CFuncTrain::OverrideReset( void )
{
	CBaseEntity	*pTarg;

	// Are we moving?
	if( pev->velocity != g_vecZero && pev->nextthink != 0 )
	{
		pev->target = pev->message;
		// now find our next target
		pTarg = GetNextTarget();
		if( !pTarg )
		{
			pev->nextthink = 0;
			pev->velocity = g_vecZero;
		}
		else	// Keep moving for 0.1 secs, then find path_corner again and restart
		{
			SetThink( &CFuncTrain::Next );
			pev->nextthink = pev->ltime + 0.1;
		}
	}
}
Ejemplo n.º 17
0
	void CActionDungeonEdgeFree::DoAction()
	{
		for(DWORD objectIndex = GetHeadTarget();
			objectIndex > 0;
			objectIndex = GetNextTarget())
		{
			CObject* const object = g_pUserTable->FindUser(objectIndex);

			if(0 == object)
			{
				continue;
			}

			MSG_DWORD3	msg;
			msg.Category = MP_DUNGEON;
			msg.Protocol = MP_DUNGEON_EDGEFREE;
			msg.dwObjectID = object->GetID();
			msg.dwData1 = GetValue(eProperty_RangeX);
			msg.dwData2 = GetValue(eProperty_RangeZ);
			msg.dwData3 = GetValue(eProperty_Range);
			object->SendMsg(&msg, sizeof(msg));
		}
	}
Ejemplo n.º 18
0
//------------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
CScriptedTarget* CScriptedTarget::NextScriptedTarget(void)
{
	// ----------------------------------------------------------------------
	// If I just hit my target, set how long I'm supposed to pause here
	// ----------------------------------------------------------------------
	if (m_flPauseDoneTime == 0)
	{
		m_flPauseDoneTime = gpGlobals->curtime + m_flPauseDuration;
		m_AtTarget.FireOutput( GetTarget(), this );
	}

	// -------------------------------------------------------------
	// If I'm done pausing move on to next burn target
	// -------------------------------------------------------------
	if (gpGlobals->curtime >= m_flPauseDoneTime)
	{
		m_flPauseDoneTime = 0;

		// ----------------------------------------------------------
		//  Fire output that current Scripted target has been reached
		// ----------------------------------------------------------
		m_LeaveTarget.FireOutput( GetTarget(), this );

		// ------------------------------------------------------------
		//  Get next target.  
		// ------------------------------------------------------------
		CScriptedTarget* pNextTarget = ((CScriptedTarget*)GetNextTarget());

		// --------------------------------------------
		//	Fire output if last one has been reached
		// --------------------------------------------
		if (!pNextTarget)
		{
			TurnOff();
			SetTarget( NULL );
		}
		// ------------------------------------------------
		//	Otherwise, turn myself off, the next target on
		//  and pass on my target entity
		// ------------------------------------------------
		else
		{
			// ----------------------------------------------------
			//  Make sure there is a LOS between these two targets
			// ----------------------------------------------------
			trace_t tr;
			UTIL_TraceLine(GetAbsOrigin(), pNextTarget->GetAbsOrigin(), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr);	
			if (tr.fraction != 1.0)
			{
				Warning( "WARNING: Scripted Target from (%s) to (%s) is occluded!\n",GetDebugName(),pNextTarget->GetDebugName() );
			}

			pNextTarget->TurnOn();
			pNextTarget->SetTarget( GetTarget() );

			SetTarget( NULL );
			TurnOff();
		}
		// --------------------------------------------
		//	Return new target
		// --------------------------------------------
		return pNextTarget;
	}
	// -------------------------------------------------------------
	//  Otherwise keep the same scripted target until pause is done
	// -------------------------------------------------------------
	else
	{
		return this;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CASW_Broadcast_Camera::Enable( void )
{
	m_state = USE_ON;

	//if ( !m_hPlayer || !m_hPlayer->IsPlayer() )
	//{
		//m_hPlayer = UTIL_GetLocalPlayer();
	//}

	//if ( !m_hPlayer )
	//{
		//DispatchUpdateTransmitState();
		//return;
	//}

	//if ( m_hPlayer->IsPlayer() )
	//{
		 //m_nPlayerButtons = ((CBasePlayer*)m_hPlayer.Get())->m_nButtons;
	//}
	
	//if ( HasSpawnFlags( SF_CAMERA_PLAYER_NOT_SOLID ) )
	//{
		//m_hPlayer->AddSolidFlags( FSOLID_NOT_SOLID );
	//}
	
	m_flReturnTime = gpGlobals->curtime + m_flWait;
	m_flSpeed = m_initialSpeed;
	m_targetSpeed = m_initialSpeed;

	if ( HasSpawnFlags( SF_CAMERA_PLAYER_SNAP_TO ) )
	{
		m_bSnapToGoal = true;
	}

	//if ( HasSpawnFlags(SF_CAMERA_PLAYER_TARGET ) )
	//{
		//m_hTarget = m_hPlayer;
	//}
	//else
	//{
		m_hTarget = GetNextTarget();
	//}

	// If we don't have a target, ignore the attachment / etc
	if ( m_hTarget )
	{
		m_iAttachmentIndex = 0;
		if ( m_iszTargetAttachment != NULL_STRING )
		{
			if ( !m_hTarget->GetBaseAnimating() )
			{
				Warning("%s tried to target an attachment (%s) on target %s, which has no model.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) );
			}
			else
			{
				m_iAttachmentIndex = m_hTarget->GetBaseAnimating()->LookupAttachment( STRING(m_iszTargetAttachment) );
				if ( !m_iAttachmentIndex )
				{
					Warning("%s could not find attachment %s on target %s.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) );
				}
			}
		}
	}

	//if (HasSpawnFlags(SF_CAMERA_PLAYER_TAKECONTROL ) )
	//{
		//((CBasePlayer*)m_hPlayer.Get())->EnableControl(FALSE);
	//}

	if ( m_sPath != NULL_STRING )
	{
		m_pPath = gEntList.FindEntityByName( NULL, m_sPath, NULL); //, m_hPlayer );
	}
	else
	{
		m_pPath = NULL;
	}

	m_flStopTime = gpGlobals->curtime;
	if ( m_pPath )
	{
		if ( m_pPath->m_flSpeed != 0 )
			m_targetSpeed = m_pPath->m_flSpeed;
		
		m_flStopTime += m_pPath->GetDelay();
		m_vecMoveDir = m_pPath->GetLocalOrigin() - GetLocalOrigin();
		m_moveDistance = VectorNormalize( m_vecMoveDir );
		m_flStopTime = gpGlobals->curtime + m_pPath->GetDelay();
	}
	else
	{
		m_moveDistance = 0;
	}
	/*
	if ( m_pPath )
	{
		if ( m_pPath->m_flSpeed != 0 )
			m_targetSpeed = m_pPath->m_flSpeed;
		
		Msg("target speed is %f\n", m_targetSpeed);
		m_flStopTime += m_pPath->GetDelay();
	}
	*/

	// copy over player information
	//if (HasSpawnFlags(SF_CAMERA_PLAYER_POSITION ) )
	//{
		//UTIL_SetOrigin( this, m_hPlayer->EyePosition() );
		//SetLocalAngles( QAngle( m_hPlayer->GetLocalAngles().x, m_hPlayer->GetLocalAngles().y, 0 ) );
		//SetAbsVelocity( m_hPlayer->GetAbsVelocity() );
	//}
	//else
	//{
		SetAbsVelocity( vec3_origin );
	//}

	UpdateAllPlayers();
	//((CBasePlayer*)m_hPlayer.Get())->SetViewEntity( this );

	// Hide the player's viewmodel
	//if ( ((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon() )
	//{
		//((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon()->AddEffects( EF_NODRAW );
	//}

	// Only track if we have a target
	if ( m_hTarget )
	{
		// follow the player down
		SetThink( &CASW_Broadcast_Camera::FollowTarget );
		SetNextThink( gpGlobals->curtime );
	}

	//m_moveDistance = 0;
	m_vecLastPos = GetAbsOrigin();
	Move();

	DispatchUpdateTransmitState();
}
Ejemplo n.º 20
0
bool AIInterface::IsValidUnitTarget( Object *pObject, uint32 pFilter, float pMinRange, float pMaxRange )
{
	// Make sure its a valid unit
	if (!pObject->IsUnit() )
		return false;

	Unit *UnitTarget = TO_UNIT( pObject );
	if ( UnitTarget->GetInstanceID() != m_Unit->GetInstanceID() )
		return false;

//	if ( !m_is_in_instance ) // skip instance check for spell casting
	if ( m_outOfCombatRange )
		if ( UnitTarget->GetDistanceSq( GetReturnPos() ) > m_outOfCombatRange )
			return false;
	float dist = m_Unit->CalcDistance( UnitTarget );
	if ( UnitTarget != m_nextTarget )
		if ( dist > _CalcAggroRange( UnitTarget ) )
			return false;

	if ( pFilter & TargetFilter_Corpse )
	{	//Skip dead ( if required ), feign death or invisible targets
		if ( UnitTarget->isAlive() || !UnitTarget->IsCreature() || TO_CREATURE( UnitTarget )->creature_info->Rank == ELITE_WORLDBOSS )
			return false;
	}
	else if ( !UnitTarget->isAlive() )
		return false;

	if ( UnitTarget->IsPlayer() && TO_PLAYER( UnitTarget )->m_isGmInvisible )
		return false;
	if ( UnitTarget->HasFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_FEIGN_DEATH ) )
		return false;

	//Check if we apply target filtering
	if ( pFilter != TargetFilter_None )
	{
		//Skip units not on threat list
		if ( ( pFilter & TargetFilter_Aggroed ) && getThreatByPtr( UnitTarget ) == 0 )
			return false;

		//Skip current attacking target if requested
		if ( ( pFilter & TargetFilter_NotCurrent ) && UnitTarget == GetNextTarget() )
			return false;

		//Keep only wounded targets if requested
		if ( ( pFilter & TargetFilter_Wounded ) && UnitTarget->GetHealthPct() >= 99 )
			return false;

		//Skip targets not in melee range if requested
		if ( ( pFilter & TargetFilter_InMeleeRange ) && dist > _CalcCombatRange( UnitTarget, false ) )
			return false;

		//Skip targets not in strict range if requested
		if ( ( pFilter & TargetFilter_InRangeOnly ) && ( pMinRange > 0 || pMaxRange > 0 ) )
		{
			if ( pMinRange > 0 && dist < pMinRange )
				return false;
			if ( pMaxRange > 0 && dist > pMaxRange )
				return false;
		}

		//Skip targets not in Line Of Sight if requested
		if ( ( ~pFilter & TargetFilter_IgnoreLineOfSight ) && !m_Unit->IsInLineOfSight( UnitTarget ) )
			return false;

		//Handle hostile/friendly
		if ( ( ~pFilter & TargetFilter_Corpse ) && ( pFilter & TargetFilter_Friendly ) ) 
		{
			if ( !UnitTarget->CombatStatus.IsInCombat() )
				return false; //Skip not-in-combat targets if friendly
			if ( isHostile( m_Unit, UnitTarget ) || getThreatByPtr( UnitTarget ) > 0 )
				return false;
		}
	}

	return true; //This is a valid unit target
}