Beispiel #1
0
void CHgun::SecondaryAttack( void )
{
	Reload();

	if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
	{
		return;
	}

	//Wouldn't be a bad idea to completely predict these, since they fly so fast...
#ifndef CLIENT_DLL
	CBaseEntity *pHornet;
	Vector vecSrc;

	UTIL_MakeVectors( m_pPlayer->pev->v_angle );

	vecSrc = m_pPlayer->GetGunPosition( ) + gpGlobals->v_forward * 16 + gpGlobals->v_right * 8 + gpGlobals->v_up * -12;

	m_iFirePhase++;
	switch ( m_iFirePhase )
	{
	case 1:
		vecSrc = vecSrc + gpGlobals->v_up * 8;
		break;
	case 2:
		vecSrc = vecSrc + gpGlobals->v_up * 8;
		vecSrc = vecSrc + gpGlobals->v_right * 8;
		break;
	case 3:
		vecSrc = vecSrc + gpGlobals->v_right * 8;
		break;
	case 4:
		vecSrc = vecSrc + gpGlobals->v_up * -8;
		vecSrc = vecSrc + gpGlobals->v_right * 8;
		break;
	case 5:
		vecSrc = vecSrc + gpGlobals->v_up * -8;
		break;
	case 6:
		vecSrc = vecSrc + gpGlobals->v_up * -8;
		vecSrc = vecSrc + gpGlobals->v_right * -8;
		break;
	case 7:
		vecSrc = vecSrc + gpGlobals->v_right * -8;
		break;
	case 8:
		vecSrc = vecSrc + gpGlobals->v_up * 8;
		vecSrc = vecSrc + gpGlobals->v_right * -8;
		m_iFirePhase = 0;
		break;
	}

	pHornet = CBaseEntity::Create( "hornet", vecSrc, m_pPlayer->pev->v_angle, m_pPlayer->edict() );
	pHornet->pev->velocity = gpGlobals->v_forward * 1200;
	pHornet->pev->angles = UTIL_VecToAngles( pHornet->pev->velocity );

	pHornet->SetThink( &CHornet::StartDart );

	m_flRechargeTime = gpGlobals->time + 0.5;
#endif

	int flags;
#if defined( CLIENT_WEAPONS )
	flags = FEV_NOTHOST;
#else
	flags = 0;
#endif

	PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, FIREMODE_FAST, 0, 0, 0 );


	m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
	m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
	m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH;

		// player "shoot" animation
	m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

	m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.1;
	m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}
Beispiel #2
0
void CBasePlayer::SimulatePlayerSimulatedEntities( void )
{
	int c = m_SimulatedByThisPlayer.Count();
	int i;

	for ( i = c - 1; i >= 0; i-- )
	{
		CHandle< CBaseEntity > h;
		
		h = m_SimulatedByThisPlayer[ i ];
		CBaseEntity *e = h;

		if ( !e || !e->IsPlayerSimulated() )
		{
			m_SimulatedByThisPlayer.Remove( i );
			continue;
		}

#if defined( CLIENT_DLL )
		if ( e->IsClientCreated() && prediction->InPrediction() && !prediction->IsFirstTimePredicted() )
		{
			continue;
		}
#endif
		Assert( e->IsPlayerSimulated() );
		Assert( e->GetSimulatingPlayer() == this );

		e->PhysicsSimulate();
	}

	// Loop through all entities again, checking their untouch if flagged to do so
	c = m_SimulatedByThisPlayer.Count();

	for ( i = c - 1; i >= 0; i-- )
	{
		CHandle< CBaseEntity > h;
		
		h = m_SimulatedByThisPlayer[ i ];

		CBaseEntity *e = h;
		if ( !e || !e->IsPlayerSimulated() )
		{
			m_SimulatedByThisPlayer.Remove( i );
			continue;
		}

#if defined( CLIENT_DLL )
		if ( e->IsClientCreated() && prediction->InPrediction() && !prediction->IsFirstTimePredicted() )
		{
			continue;
		}
#endif

		Assert( e->IsPlayerSimulated() );
		Assert( e->GetSimulatingPlayer() == this );

		if ( !e->GetCheckUntouch() )
			continue;

		e->PhysicsCheckForEntityUntouch();
	}
}
Beispiel #3
0
/* <1bc358> ../cstrike/dlls/vehicle.cpp:466 */
void CFuncVehicle::CollisionDetection()
{
    TraceResult tr;
    bool bHitSomething = false;

    if (pev->speed < 0)
    {
        UTIL_TraceLine(m_vBackLeft, m_vBackLeft + (gpGlobals->v_forward * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

        if (tr.flFraction == 1.0f)
        {
            UTIL_TraceLine(m_vBackRight, m_vBackRight + (gpGlobals->v_forward * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

            if (tr.flFraction == 1.0f)
            {
                UTIL_TraceLine(m_vBack, m_vBack + (gpGlobals->v_forward * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

                if (tr.flFraction == 1.0f)
                {
                    return;
                }
            }

            if (DotProduct(gpGlobals->v_forward, tr.vecPlaneNormal * -1.0) < 0.7 && tr.vecPlaneNormal.z < 0.1)
            {
                m_vSurfaceNormal = tr.vecPlaneNormal;
                m_vSurfaceNormal.z = 0;

                pev->speed *= 0.99;
            }
            else if (tr.vecPlaneNormal.z < 0.65 || tr.fStartSolid)
            {
                pev->speed *= -1.0;
            }
            else
            {
                m_vSurfaceNormal = tr.vecPlaneNormal;
            }
        }
        else
        {
            if (DotProduct(gpGlobals->v_forward, tr.vecPlaneNormal * -1.0) < 0.7 && tr.vecPlaneNormal.z < 0.1)
            {
                m_vSurfaceNormal = tr.vecPlaneNormal;
                m_vSurfaceNormal.z = 0;

                pev->speed *= 0.99;
            }
            else if (tr.vecPlaneNormal[2] < 0.65 || tr.fStartSolid)
            {
                pev->speed *= -1.0;
            }
            else
            {
                m_vSurfaceNormal = tr.vecPlaneNormal;
            }

            CBaseEntity *pHit = CBaseEntity::Instance(tr.pHit);

            if (pHit && pHit->Classify() == CLASS_VEHICLE)
            {
                bHitSomething = true;
                ALERT(at_console, "I hit another vehicle\n");
            }
        }
    }
    else if (pev->speed > 0)
    {
        UTIL_TraceLine(m_vFrontLeft, m_vFrontLeft - (gpGlobals->v_forward * 16.0), dont_ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

        if (tr.flFraction == 1.0f)
        {
            UTIL_TraceLine(m_vFrontRight, m_vFrontRight - (gpGlobals->v_forward * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

            if (tr.flFraction == 1.0f)
            {
                UTIL_TraceLine(m_vFront, m_vFront - (gpGlobals->v_forward * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr);

                if (tr.flFraction == 1.0f)
                {
                    return;
                }
            }
        }

        if (DotProduct(gpGlobals->v_forward, tr.vecPlaneNormal * -1.0) > -0.7 && tr.vecPlaneNormal.z < 0.1)
        {
            m_vSurfaceNormal = tr.vecPlaneNormal;
            m_vSurfaceNormal.z = 0;

            pev->speed *= 0.99;
        }
        else if (tr.vecPlaneNormal.z < 0.65 || tr.fStartSolid)
        {
            pev->speed *= -1.0;
        }
        else
        {
            m_vSurfaceNormal = tr.vecPlaneNormal;
        }
    }
}
Beispiel #4
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flDot - 
//			flDist - 
// Output : int
//-----------------------------------------------------------------------------
int CWeaponSMG1::WeaponRangeAttack2Condition( float flDot, float flDist )
{
	CAI_BaseNPC *npcOwner = GetOwner()->MyNPCPointer();

	return COND_NONE;

/*
	// --------------------------------------------------------
	// Assume things haven't changed too much since last time
	// --------------------------------------------------------
	if (gpGlobals->curtime < m_flNextGrenadeCheck )
		return m_lastGrenadeCondition;
*/

	// -----------------------
	// If moving, don't check.
	// -----------------------
	if ( npcOwner->IsMoving())
		return COND_NONE;

	CBaseEntity *pEnemy = npcOwner->GetEnemy();

	if (!pEnemy)
		return COND_NONE;

	Vector vecEnemyLKP = npcOwner->GetEnemyLKP();
	if ( !( pEnemy->GetFlags() & FL_ONGROUND ) && pEnemy->GetWaterLevel() == 0 && vecEnemyLKP.z > (GetAbsOrigin().z + WorldAlignMaxs().z) )
	{
		//!!!BUGBUG - we should make this check movetype and make sure it isn't FLY? Players who jump a lot are unlikely to 
		// be grenaded.
		// don't throw grenades at anything that isn't on the ground!
		return COND_NONE;
	}
	
	// --------------------------------------
	//  Get target vector
	// --------------------------------------
	Vector vecTarget;
	if (random->RandomInt(0,1))
	{
		// magically know where they are
		vecTarget = pEnemy->WorldSpaceCenter();
	}
	else
	{
		// toss it to where you last saw them
		vecTarget = vecEnemyLKP;
	}
	// vecTarget = m_vecEnemyLKP + (pEnemy->BodyTarget( GetLocalOrigin() ) - pEnemy->GetLocalOrigin());
	// estimate position
	// vecTarget = vecTarget + pEnemy->m_vecVelocity * 2;


	if ( ( vecTarget - npcOwner->GetLocalOrigin() ).Length2D() <= COMBINE_MIN_GRENADE_CLEAR_DIST )
	{
		// crap, I don't want to blow myself up
		m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second.
		return (COND_NONE);
	}

	// ---------------------------------------------------------------------
	// Are any friendlies near the intended grenade impact area?
	// ---------------------------------------------------------------------
	CBaseEntity *pTarget = NULL;

	while ( ( pTarget = gEntList.FindEntityInSphere( pTarget, vecTarget, COMBINE_MIN_GRENADE_CLEAR_DIST ) ) != NULL )
	{
		//Check to see if the default relationship is hatred, and if so intensify that
		if ( npcOwner->IRelationType( pTarget ) == D_LI )
		{
			// crap, I might blow my own guy up. Don't throw a grenade and don't check again for a while.
			m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second.
			return (COND_WEAPON_BLOCKED_BY_FRIEND);
		}
	}

	// ---------------------------------------------------------------------
	// Check that throw is legal and clear
	// ---------------------------------------------------------------------
	// FIXME: speed is based on difficulty...

	Vector vecToss = VecCheckThrow( this, npcOwner->GetLocalOrigin() + Vector(0,0,60), vecTarget, 600.0, 0.5 );
	if ( vecToss != vec3_origin )
	{
		m_vecTossVelocity = vecToss;

		// don't check again for a while.
		// JAY: HL1 keeps checking - test?
		//m_flNextGrenadeCheck = gpGlobals->curtime;
		m_flNextGrenadeCheck = gpGlobals->curtime + 0.3; // 1/3 second.
		return COND_CAN_RANGE_ATTACK2;
	}
	else
	{
		// don't check again for a while.
		m_flNextGrenadeCheck = gpGlobals->curtime + 1; // one full second.
		return COND_WEAPON_SIGHT_OCCLUDED;
	}
}
Beispiel #5
0
int CAI_LeadBehavior::SelectSchedule()
{
    if (HasGoal())
    {
        if (HasCondition(COND_LEAD_SUCCESS))
        {
            return SCHED_LEAD_SUCCEED;
        }

        // Player's here, but does he have the weapon we want him to have?
        if (m_weaponname != NULL_STRING)
        {
            CBasePlayer *pFollower = AI_GetSinglePlayer();
            if (pFollower && !pFollower->Weapon_OwnsThisType(STRING(m_weaponname)))
            {
                // If the safety timeout has run out, just give the player the weapon
                if (!m_flWeaponSafetyTimeOut || (m_flWeaponSafetyTimeOut > gpGlobals->curtime))
                    return SCHED_LEAD_PLAYERNEEDSWEAPON;

                string_t iszItem = AllocPooledString("weapon_bugbait");
                pFollower->GiveNamedItem(STRING(iszItem));
            }
        }

        // If we have a waitpoint, we want to wait at it for the player.
        if (HasWaitPoint() && !PlayerIsAheadOfMe(true))
        {
            bool bKeepWaiting = true;

            // If we have no wait distance, trigger as soon as the player comes in view
            if (!m_waitdistance)
            {
                if (HasCondition(COND_SEE_PLAYER))
                {
                    // We've spotted the player, so stop waiting
                    bKeepWaiting = false;
                }
            }
            else
            {
                // We have to collect data about the person we're leading around.
                CBaseEntity *pFollower = AI_GetSinglePlayer();
                if (pFollower)
                {
                    float flFollowerDist = (WorldSpaceCenter() - pFollower->WorldSpaceCenter()).Length();
                    if (flFollowerDist < m_waitdistance)
                    {
                        bKeepWaiting = false;
                    }
                }
            }

            // Player still not here?
            if (bKeepWaiting)
                return SCHED_LEAD_WAITFORPLAYER;

            // We're finished waiting
            m_waitpoint = vec3_origin;
            Speak(TLK_LEAD_WAITOVER);

            // Don't speak the start line, because we've said 
            m_hasspokenstart = true;
            return SCHED_WAIT_FOR_SPEAK_FINISH;
        }

        // If we haven't spoken our start speech, do that first
        if (!m_hasspokenstart)
        {
            if (HasCondition(COND_LEAD_HAVE_FOLLOWER_LOS) && HasCondition(COND_LEAD_FOLLOWER_VERY_CLOSE))
                return SCHED_LEAD_SPEAK_START;

            // We haven't spoken to him, and we still need to. Go get him.
            return SCHED_LEAD_RETRIEVE;
        }

        if (HasCondition(COND_LEAD_FOLLOWER_LOST))
        {
            if (m_args.iRetrievePlayer)
            {
                // If not, we want to go get the player.
                DevMsg(GetOuter(), "Follower lost. Spoke COMING_BACK.\n");

                Speak(TLK_LEAD_COMINGBACK);
                m_MoveMonitor.ClearMark();

                // If we spoke something, wait for it to finish
                if (m_args.iComingBackWaitForSpeak && IsSpeaking())
                    return SCHED_LEAD_SPEAK_THEN_RETRIEVE_PLAYER;

                return SCHED_LEAD_RETRIEVE;
            }
            else
            {
                // Just stay right here and wait.
                return SCHED_LEAD_WAITFORPLAYERIDLE;
            }
        }

        if (HasCondition(COND_LEAD_FOLLOWER_LAGGING))
        {
            DevMsg(GetOuter(), "Follower lagging. Spoke CATCHUP.\n");

            Speak(TLK_LEAD_CATCHUP);
            return SCHED_LEAD_PAUSE;
        }
        else
        {
            // If we're at the goal, wait for the player to get here
            if ((WorldSpaceCenter() - m_goal).LengthSqr() < (64 * 64))
                return SCHED_LEAD_AWAIT_SUCCESS;

            // If we were retrieving the player, speak the resume
            if (IsCurSchedule(SCHED_LEAD_RETRIEVE, false) || IsCurSchedule(SCHED_LEAD_WAITFORPLAYERIDLE, false))
            {
                Speak(TLK_LEAD_RETRIEVE);

                // If we spoke something, wait for it to finish, if the mapmakers wants us to
                if (m_args.iRetrieveWaitForSpeak && IsSpeaking())
                    return SCHED_LEAD_SPEAK_THEN_LEAD_PLAYER;
            }

            DevMsg(GetOuter(), "Leading Follower.\n");
            return SCHED_LEAD_PLAYER;
        }
    }
    return BaseClass::SelectSchedule();
}
IterationRetval_t CPortalCollideableEnumerator::EnumElement( IHandleEntity *pHandleEntity )
{
	EHANDLE hEnt = pHandleEntity->GetRefEHandle();
	
	CBaseEntity *pEnt = hEnt.Get();
	if( pEnt == NULL ) //I really never thought this would be necessary
		return ITERATION_CONTINUE;
	
	if( hEnt == m_hTestPortal )
		return ITERATION_CONTINUE; //ignore this portal

	/*if( staticpropmgr->IsStaticProp( pHandleEntity ) )
	{
		//we're dealing with a static prop, which unfortunately doesn't have everything I want to use for checking
		
		ICollideable *pCollideable = pEnt->GetCollideable();

		Vector vMins, vMaxs;
		pCollideable->WorldSpaceSurroundingBounds( &vMins, &vMaxs );

		Vector ptTest( (m_vPlaneNormal.x > 0.0f)?(vMaxs.x):(vMins.x),
						(m_vPlaneNormal.y > 0.0f)?(vMaxs.y):(vMins.y),
						(m_vPlaneNormal.z > 0.0f)?(vMaxs.z):(vMins.z) );
	
		float fPtPlaneDist = m_vPlaneNormal.Dot( ptTest ) - m_fPlaneDist;
		if( fPtPlaneDist <= 0.0f )
			return ITERATION_CONTINUE;
	}
	else*/
	{
		//not a static prop, w00t
		CCollisionProperty *pEntityCollision = pEnt->CollisionProp();

		if( !pEntityCollision->IsSolid() )
			return ITERATION_CONTINUE; //not solid

		Vector ptEntCenter = pEntityCollision->WorldSpaceCenter();

		float fBoundRadius = pEntityCollision->BoundingRadius();
		float fPtPlaneDist = m_vPlaneNormal.Dot( ptEntCenter ) - m_fPlaneDist;

		if( fPtPlaneDist < -fBoundRadius )
			return ITERATION_CONTINUE; //object wholly behind the portal

		if( !(fPtPlaneDist > fBoundRadius) && (fPtPlaneDist > -fBoundRadius) ) //object is not wholly in front of the portal, but could be partially in front, do more checks
		{
			Vector ptNearest;
			pEntityCollision->CalcNearestPoint( m_ptForward1000, &ptNearest );
			fPtPlaneDist = m_vPlaneNormal.Dot( ptNearest ) - m_fPlaneDist;
			if( fPtPlaneDist < 0.0f )
				return ITERATION_CONTINUE; //closest point was behind the portal plane, we don't want it
		}


	}

	//if we're down here, this entity needs to be added to our enumeration
	Assert( m_iHandleCount < 1024 );
	if( m_iHandleCount < 1024 ) 
		m_pHandles[m_iHandleCount] = pHandleEntity;
	++m_iHandleCount;

	return ITERATION_CONTINUE;
}
Beispiel #7
0
//-----------------------------------------------------------------------------
// Purpose: Only called on BSP load. Parses and spawns all the entities in the BSP.
// Input  : pMapData - Pointer to the entity data block to parse.
//-----------------------------------------------------------------------------
void MapEntity_ParseAllEntities(const char *pMapData, IMapEntityFilter *pFilter, bool bActivateEntities)
{
	VPROF("MapEntity_ParseAllEntities");

	HierarchicalSpawnMapData_t pSpawnMapData[NUM_ENT_ENTRIES];
	HierarchicalSpawn_t pSpawnList[NUM_ENT_ENTRIES];
	CUtlVector< CPointTemplate* > pPointTemplates;
	int nEntities = 0;

	char szTokenBuffer[MAPKEY_MAXLENGTH];

#if !defined( _RETAIL )
#if defined( _XBOX )
	char sz[ 128 ];
	Q_snprintf( sz, sizeof( sz ), "MapEntity_ParseAllEntities():Start" );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif
	// Allow the tools to spawn different things
	if ( serverenginetools )
	{
		pMapData = serverenginetools->GetEntityData( pMapData );
	}

	//  Loop through all entities in the map data, creating each.
	for ( ; true; pMapData = MapEntity_SkipToNextEntity(pMapData, szTokenBuffer) )
	{
		//
		// Parse the opening brace.
		//
		char token[MAPKEY_MAXLENGTH];
		pMapData = MapEntity_ParseToken( pMapData, token );

		//
		// Check to see if we've finished or not.
		//
		if (!pMapData)
			break;

		if (token[0] != '{')
		{
			Error( "MapEntity_ParseAllEntities: found %s when expecting {", token);
			continue;
		}

		//
		// Parse the entity and add it to the spawn list.
		//
		CBaseEntity *pEntity;
		const char *pCurMapData = pMapData;
		pMapData = MapEntity_ParseEntity(pEntity, pMapData, pFilter);
		if (pEntity == NULL)
			continue;

		if (pEntity->IsTemplate())
		{
			// It's a template entity. Squirrel away its keyvalue text so that we can
			// recreate the entity later via a spawner. pMapData points at the '}'
			// so we must add one to include it in the string.
			Templates_Add(pEntity, pCurMapData, (pMapData - pCurMapData) + 2);

			// Remove the template entity so that it does not show up in FindEntityXXX searches.
			UTIL_Remove(pEntity);
			gEntList.CleanupDeleteList();
			continue;
		}

		// To 
		if ( dynamic_cast<CWorld*>( pEntity ) )
		{
			VPROF( "MapEntity_ParseAllEntities_SpawnWorld");

			pEntity->m_iParent = NULL_STRING;	// don't allow a parent on the first entity (worldspawn)

			DispatchSpawn(pEntity);
			continue;
		}
				
		CNodeEnt *pNode = dynamic_cast<CNodeEnt*>(pEntity);
		if ( pNode )
		{
			VPROF( "MapEntity_ParseAllEntities_SpawnTransients");

			// We overflow the max edicts on large maps that have lots of entities.
			// Nodes & Lights remove themselves immediately on Spawn(), so dispatch their
			// spawn now, to free up the slot inside this loop.
			// NOTE: This solution prevents nodes & lights from being used inside point_templates.
			//
			// NOTE: Nodes spawn other entities (ai_hint) if they need to have a persistent presence.
			//		 To ensure keys are copied over into the new entity, we pass the mapdata into the
			//		 node spawn function.
			if ( pNode->Spawn( pCurMapData ) < 0 )
			{
				gEntList.CleanupDeleteList();
			}
			continue;
		}

		if ( dynamic_cast<CLight*>(pEntity) )
		{
			VPROF( "MapEntity_ParseAllEntities_SpawnTransients");

			// We overflow the max edicts on large maps that have lots of entities.
			// Nodes & Lights remove themselves immediately on Spawn(), so dispatch their
			// spawn now, to free up the slot inside this loop.
			// NOTE: This solution prevents nodes & lights from being used inside point_templates.
			if (DispatchSpawn(pEntity) < 0)
			{
				gEntList.CleanupDeleteList();
			}
			continue;
		}

		// Build a list of all point_template's so we can spawn them before everything else
		CPointTemplate *pTemplate = dynamic_cast< CPointTemplate* >(pEntity);
		if ( pTemplate )
		{
			pPointTemplates.AddToTail( pTemplate );
		}
		else
		{
			// Queue up this entity for spawning
			pSpawnList[nEntities].m_pEntity = pEntity;
			pSpawnList[nEntities].m_nDepth = 0;
			pSpawnMapData[nEntities].m_pMapData = pCurMapData;
			pSpawnMapData[nEntities].m_iMapDataLength = (pMapData - pCurMapData) + 2;
			nEntities++;
		}
	}
#if !defined( _RETAIL )
#if defined( _XBOX )
	Q_snprintf( sz, sizeof( sz ), "Template Spawn:Start" );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif
	// Now loop through all our point_template entities and tell them to make templates of everything they're pointing to
	int iTemplates = pPointTemplates.Count();
	for ( int i = 0; i < iTemplates; i++ )
	{
		VPROF( "MapEntity_ParseAllEntities_SpawnTemplates");
		CPointTemplate *pPointTemplate = pPointTemplates[i];

		// First, tell the Point template to Spawn
		if ( DispatchSpawn(pPointTemplate) < 0 )
		{
			UTIL_Remove(pPointTemplate);
			gEntList.CleanupDeleteList();
			continue;
		}

		pPointTemplate->StartBuildingTemplates();

		// Now go through all it's templates and turn the entities into templates
		int iNumTemplates = pPointTemplate->GetNumTemplateEntities();
		for ( int iTemplateNum = 0; iTemplateNum < iNumTemplates; iTemplateNum++ )
		{
			// Find it in the spawn list
			CBaseEntity *pEntity = pPointTemplate->GetTemplateEntity( iTemplateNum );
			for ( int iEntNum = 0; iEntNum < nEntities; iEntNum++ )
			{
				if ( pSpawnList[iEntNum].m_pEntity == pEntity )
				{
					// Give the point_template the mapdata
					pPointTemplate->AddTemplate( pEntity, pSpawnMapData[iEntNum].m_pMapData, pSpawnMapData[iEntNum].m_iMapDataLength );

					if ( pPointTemplate->ShouldRemoveTemplateEntities() )
					{
						// Remove the template entity so that it does not show up in FindEntityXXX searches.
						UTIL_Remove(pEntity);
						gEntList.CleanupDeleteList();

						// Remove the entity from the spawn list
						pSpawnList[iEntNum].m_pEntity = NULL;
					}
					break;
				}
			}
		}

		pPointTemplate->FinishBuildingTemplates();
	}

#if !defined( _RETAIL )
#if defined( _XBOX )
	Q_snprintf( sz, sizeof( sz ), "Template Spawn:Finish" );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif

	SpawnHierarchicalList( nEntities, pSpawnList, bActivateEntities );

#if !defined( _RETAIL )
#if defined( _XBOX )
	Q_snprintf( sz, sizeof( sz ), "SpawnHierarchicalList" );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif
}
void CASW_Simple_Alien::MeleeAttack( float distance, float damage, QAngle &viewPunch, Vector &shove )
{
	Vector vecForceDir;

	// Always hurt bullseyes for now
	if ( ( GetEnemy() != NULL ) && ( GetEnemy()->Classify() == CLASS_BULLSEYE ) )
	{
		vecForceDir = (GetEnemy()->GetAbsOrigin() - GetAbsOrigin());
		CTakeDamageInfo info( this, this, damage, DMG_SLASH );
		CalculateMeleeDamageForce( &info, vecForceDir, GetEnemy()->GetAbsOrigin() );
		GetEnemy()->TakeDamage( info );
		return;
	}

	CBaseEntity *pHurt = CheckTraceHullAttack( distance, -Vector(16,16,32), Vector(16,16,32), damage, DMG_SLASH, 5.0f );

	if ( pHurt )
	{
		vecForceDir = ( pHurt->WorldSpaceCenter() - WorldSpaceCenter() );

		CBasePlayer *pPlayer = ToBasePlayer( pHurt );

		if ( pPlayer != NULL )
		{
			//Kick the player angles
			pPlayer->ViewPunch( viewPunch );

			Vector	dir = pHurt->GetAbsOrigin() - GetAbsOrigin();
			VectorNormalize(dir);

			QAngle angles;
			VectorAngles( dir, angles );
			Vector forward, right;
			AngleVectors( angles, &forward, &right, NULL );

			//Push the target back
			pHurt->ApplyAbsVelocityImpulse( - right * shove[1] - forward * shove[0] );
		}

		// Play a random attack hit sound
		AttackSound();

		// bleed em
		if ( UTIL_ShouldShowBlood(pHurt->BloodColor()) )
		{
			// Hit an NPC. Bleed them!
			Vector vecBloodPos;

			Vector forward, right, up;
			AngleVectors( GetAbsAngles(), &forward, &right, &up );

			//if( GetAttachment( "leftclaw", vecBloodPos ) )
			{
				//Vector diff = vecBloodPos - GetAbsOrigin();
				//if (diff.z < 0)
					//vecBloodPos.z = GetAbsOrigin().z - (diff.z * 2);
				vecBloodPos = GetAbsOrigin() + forward * 60 - right * 14 + up * 50;
				SpawnBlood( vecBloodPos, g_vecAttackDir, pHurt->BloodColor(), MIN( damage, 30 ) );
			}

			//if( GetAttachment( "rightclaw", vecBloodPos ) )
			{				
				vecBloodPos = GetAbsOrigin() + forward * 60 + right * 14 + up * 50;
				SpawnBlood( vecBloodPos, g_vecAttackDir, pHurt->BloodColor(), MIN( damage, 30 ) );
			}
						
		}
	}
}
Beispiel #9
0
void AvHBaseBuildable::WorldUpdate()
{
	this->UpdateTechSlots();

	// Organic buildings heal themselves
	if(this->GetIsOrganic())
	{
		this->UpdateAutoHeal();
	}
	else
	{
		//this->UpdateDamageEffects();
	}

	// If we're electrified, set render mode
	if(GetHasUpgrade(this->pev->iuser4, MASK_UPGRADE_11))
	{
		// Base marine building
		const int kElectrifyRenderMode = kRenderFxGlowShell;
		const int kElectrifyRenderAmount = 40;

		this->pev->renderfx = kElectrifyRenderMode;
		this->pev->renderamt = kElectrifyRenderAmount;
		this->pev->rendercolor.x = kTeamColors[this->pev->team][0];
		this->pev->rendercolor.y = kTeamColors[this->pev->team][1];
		this->pev->rendercolor.z = kTeamColors[this->pev->team][2];

		// Check for enemy players/structures nearby
		CBaseEntity* theBaseEntity = NULL;
		int theNumEntsDamaged = 0;
		
		while(((theBaseEntity = UTIL_FindEntityInSphere(theBaseEntity, this->pev->origin, BALANCE_VAR(kElectricalRange))) != NULL) && (theNumEntsDamaged < BALANCE_VAR(kElectricalMaxTargets)))
		{
			// When "electric" cheat is enabled, shock all non-self entities, else shock enemies
			if((GetGameRules()->GetIsCheatEnabled(kcElectric) && (theBaseEntity != this)) || ((theBaseEntity->pev->team != this->pev->team) && theBaseEntity->IsAlive()))
			{
				// Make sure it's not blocked
				TraceResult theTraceResult;
				UTIL_TraceLine(this->pev->origin, theBaseEntity->pev->origin, ignore_monsters, dont_ignore_glass, this->edict(), &theTraceResult);
				if(theTraceResult.flFraction == 1.0f)
				{
					CBaseEntity* theAttacker = this->GetAttacker();
					ASSERT(theAttacker);

					if(theBaseEntity->TakeDamage(this->pev, theAttacker->pev, BALANCE_VAR(kElectricalDamage), DMG_GENERIC) > 0)
					{
							MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
								WRITE_BYTE(TE_BEAMENTPOINT);
								WRITE_SHORT(theBaseEntity->entindex());
								WRITE_COORD( this->pev->origin.x);
								WRITE_COORD( this->pev->origin.y);
								WRITE_COORD( this->pev->origin.z);
						
								WRITE_SHORT( this->mElectricalSprite );
								WRITE_BYTE( 0 ); // framestart
								WRITE_BYTE( (int)15); // framerate
								WRITE_BYTE( (int)(2) ); // life
								WRITE_BYTE( 60 );  // width
								WRITE_BYTE( 15 );   // noise
								WRITE_BYTE( (int)this->pev->rendercolor.x );   // r, g, b
								WRITE_BYTE( (int)this->pev->rendercolor.y );   // r, g, b
								WRITE_BYTE( (int)this->pev->rendercolor.z );   // r, g, b
								WRITE_BYTE( 200 );	// brightness
								WRITE_BYTE( 10 );	// speed
							MESSAGE_END();
						
							gSoundListManager.PlaySoundInList(kElectricSparkSoundList, this, CHAN_AUTO, .7f);
						
							UTIL_Sparks(theBaseEntity->pev->origin);
						
							theNumEntsDamaged++;
					}
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Computes the bounding box of a beam local to the origin of the beam
//-----------------------------------------------------------------------------
void CBeam::ComputeBounds( Vector& mins, Vector& maxs )
{
	Vector vecAbsStart = GetAbsStartPos();
	Vector vecAbsEnd = GetAbsEndPos();

	// May need extra points for creating the min/max bounds
	bool bUseExtraPoints = false;
	Vector vecAbsExtra1, vecAbsExtra2;

#ifdef PORTAL
	CBaseEntity *pStartEntity = GetStartEntityPtr();

	CTraceFilterSkipClassname traceFilter( pStartEntity, "prop_energy_ball", COLLISION_GROUP_NONE );

	ITraceFilter *pEntityBeamTraceFilter = NULL;
	if ( pStartEntity )
		pEntityBeamTraceFilter = pStartEntity->GetBeamTraceFilter();

	CTraceFilterChain traceFilterChain( &traceFilter, pEntityBeamTraceFilter );

	bUseExtraPoints = UTIL_Portal_Trace_Beam( this, vecAbsStart, vecAbsEnd, vecAbsExtra1, vecAbsExtra2, &traceFilterChain );
#endif

	switch( GetType() )
	{
	case BEAM_LASER:
	case BEAM_ENTS:
	case BEAM_SPLINE:
	case BEAM_ENTPOINT:
		{
			// Compute the bounds here...
			Vector attachmentPoint( 0, 0, 0 );
			mins.Init( 99999, 99999, 99999 );
			maxs.Init( -99999, -99999, -99999 );
			for (int i = 0; i < m_nNumBeamEnts; ++i )
			{
				C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get();
				if ( pTestEnt )
				{
					if ( pTestEnt == this )
					{
						mins = maxs = GetAbsOrigin();
					}
					else
					{
						// We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments.
						Vector attMins, attMaxs;
						m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs );

						mins = mins.Min( attMins );
						mins = mins.Min( attMaxs );
						
						maxs = maxs.Max( attMins );
						maxs = maxs.Max( attMaxs );
					}
					
					//ASSERT_COORD( mins );
					//ASSERT_COORD( maxs );
				}
				else
				{
					if (i == 0)
					{
						VectorCopy( vecAbsStart, attachmentPoint );
					}
					else if (i == 1)
					{
						VectorCopy( vecAbsEnd, attachmentPoint );
					}
					else
					{
						Assert(0);
					}

					mins = mins.Min( attachmentPoint );
					maxs = maxs.Max( attachmentPoint );
				}
			}
		}
		break;

	case BEAM_POINTS:
	default:
		{
			for (int i = 0; i < 3; ++i)
			{
				if (vecAbsStart[i] < vecAbsEnd[i])
				{
					mins[i] = vecAbsStart[i];
					maxs[i] = vecAbsEnd[i];
				}
				else
				{
					mins[i] = vecAbsEnd[i];
					maxs[i] = vecAbsStart[i];
				}
			}
		}
		break;
	}

	if ( bUseExtraPoints )
	{
		mins = mins.Min( vecAbsExtra1 );
		mins = mins.Min( vecAbsExtra2 );
		maxs = maxs.Max( vecAbsExtra1 );
		maxs = maxs.Max( vecAbsExtra2 );
	}

	// Make sure the bounds are measured in *relative coords*
	Vector vecAbsOrigin = GetAbsOrigin();
	mins -= vecAbsOrigin;
	maxs -= vecAbsOrigin;
}
Beispiel #11
0
Vector CASW_Simple_Alien::CalcDeathForceVector( const CTakeDamageInfo &info )
{
	// Already have a damage force in the data, use that.
	if ( info.GetDamageForce() != vec3_origin || (g_pGameRules->Damage_NoPhysicsForce(info.GetDamageType())))
	{
		if( info.GetDamageType() & DMG_BLAST )
		{
			float scale = random->RandomFloat( 0.85, 1.15 );
			Vector force = info.GetDamageForce();
			force.x *= scale;
			force.y *= scale;
			// Try to always exaggerate the upward force because we've got pretty harsh gravity
			force.z *= (force.z > 0) ? 1.15 : scale;
			return force;
		}

		return info.GetDamageForce();
	}

	CBaseEntity *pForce = info.GetInflictor();
	if ( !pForce )
	{
		pForce = info.GetAttacker();
	}

	if ( pForce )
	{
		// Calculate an impulse large enough to push a 75kg man 4 in/sec per point of damage
		float forceScale = info.GetDamage() * 75 * 4;

		Vector forceVector;
		// If the damage is a blast, point the force vector higher than usual, this gives 
		// the ragdolls a bodacious "really got blowed up" look.
		if( info.GetDamageType() & DMG_BLAST )
		{
			// exaggerate the force from explosions a little (37.5%)
			forceVector = (GetLocalOrigin() + Vector(0, 0, WorldAlignSize().z) ) - pForce->GetLocalOrigin();
			VectorNormalize(forceVector);
			forceVector *= 1.375f;
		}
		else
		{
			// taking damage from self?  Take a little random force, but still try to collapse on the spot.
			if ( this == pForce )
			{
				forceVector.x = random->RandomFloat( -1.0f, 1.0f );
				forceVector.y = random->RandomFloat( -1.0f, 1.0f );
				forceVector.z = 0.0;
				forceScale = random->RandomFloat( 1000.0f, 2000.0f );
			}
			else
			{
				// UNDONE: Collision forces are baked in to CTakeDamageInfo now
				// UNDONE: Is this MOVETYPE_VPHYSICS code still necessary?
				if ( pForce->GetMoveType() == MOVETYPE_VPHYSICS )
				{
					// killed by a physics object
					IPhysicsObject *pPhysics = VPhysicsGetObject();
					if ( !pPhysics )
					{
						pPhysics = pForce->VPhysicsGetObject();
					}
					pPhysics->GetVelocity( &forceVector, NULL );
					forceScale = pPhysics->GetMass();
				}
				else
				{
					forceVector = GetLocalOrigin() - pForce->GetLocalOrigin();
					VectorNormalize(forceVector);
				}
			}
		}
		return forceVector * forceScale;
	}
	return vec3_origin;
}
Beispiel #12
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CNPC_Monk::GatherConditions()
{
	BaseClass::GatherConditions();

	// Build my zombie danger index!
	m_iNumZombies = 0;
	m_iDangerousZombies = 0;

	AISightIter_t iter;
	CBaseEntity *pSightEnt;
	pSightEnt = GetSenses()->GetFirstSeenEntity( &iter );
	while( pSightEnt )
	{
		if( pSightEnt->Classify() == CLASS_ZOMBIE && pSightEnt->IsAlive() )
		{
			// Is this zombie coming for me?
			CAI_BaseNPC *pZombie = dynamic_cast<CAI_BaseNPC*>(pSightEnt);
			
			if( pZombie && pZombie->GetEnemy() == this )
			{
				m_iNumZombies++;

				// if this zombie is close enough to attack, add him to the zombie danger!
				float flDist;

				flDist = (pZombie->GetAbsOrigin() - GetAbsOrigin()).Length2DSqr();

				if( flDist <= 128.0f * 128.0f )
				{
					m_iDangerousZombies++;
				}
			}
		}

		pSightEnt = GetSenses()->GetNextSeenEntity( &iter );
	}

	if( m_iDangerousZombies >= 3 || (GetEnemy() && GetHealth() < 25) )
	{
		// I see many zombies, or I'm quite injured.
		SpeakIfAllowed( TLK_HELP_ME );
	}

	// NOTE!!!!!! This code assumes grigori is using annabelle!
	ClearCondition(COND_LOW_PRIMARY_AMMO);
	if ( GetActiveWeapon() )
	{
		if ( GetActiveWeapon()->UsesPrimaryAmmo() )
		{
			if (!GetActiveWeapon()->HasPrimaryAmmo() )
			{
				SetCondition(COND_NO_PRIMARY_AMMO);
			}
			else if ( m_NPCState != NPC_STATE_COMBAT && GetActiveWeapon()->UsesClipsForAmmo1() && GetActiveWeapon()->Clip1() < 2 )
			{
				// Don't send a low ammo message unless we're not in combat.
				SetCondition(COND_LOW_PRIMARY_AMMO);
			}
		}
	}
}
Beispiel #13
0
//=========================================================
//=========================================================
void CHalfLifeTeamplay::RecountTeams( bool bResendInfo )
{
	char	*pName;
	char	teamlist[TEAMPLAY_TEAMLISTLENGTH];

	// loop through all teams, recounting everything
	num_teams = 0;

	// Copy all of the teams from the teamlist
	// make a copy because strtok is destructive
	strcpy( teamlist, m_szTeamList );
	pName = teamlist;
	pName = strtok( pName, ";" );
	while ( pName != NULL && *pName )
	{
		if ( GetTeamIndex( pName ) < 0 )
		{
			strcpy( team_names[num_teams], pName );
			num_teams++;
		}
		pName = strtok( NULL, ";" );
	}

	if ( num_teams < 2 )
	{
		num_teams = 0;
		m_teamLimit = FALSE;
	}

	// Sanity check
	memset( team_scores, 0, sizeof(team_scores) );

	// loop through all clients
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBaseEntity *plr = UTIL_PlayerByIndex( i );

		if ( plr )
		{
			const char *pTeamName = plr->TeamID();
			// try add to existing team
			int tm = GetTeamIndex( pTeamName );
			
			if ( tm < 0 ) // no team match found
			{ 
				if ( !m_teamLimit )
				{
					// add to new team
					tm = num_teams;
					num_teams++;
					team_scores[tm] = 0;
					strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH );
				}
			}

			if ( tm >= 0 )
			{
				team_scores[tm] += plr->pev->frags;
			}

			if ( bResendInfo ) //Someone's info changed, let's send the team info again.
			{
				if ( plr && IsValidTeam( plr->TeamID() ) )
				{
					MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo, NULL );
						WRITE_BYTE( plr->entindex() );
						WRITE_STRING( plr->TeamID() );
					MESSAGE_END();
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: Catches the monster-specific messages that occur when tagged
//			animation frames are played.
// Input  : *pEvent - 
//-----------------------------------------------------------------------------
void CNPC_Headcrab::HandleAnimEvent( animevent_t *pEvent )
{
	switch ( pEvent->event )
	{
		case HC_AE_JUMPATTACK:
		{
			RemoveFlag( FL_ONGROUND );

			//
			// Take him off ground so engine doesn't instantly reset FL_ONGROUND.
			//
			UTIL_SetOrigin( this, GetAbsOrigin() + Vector( 0 , 0 , 1 ));

			Vector vecJumpDir;
			CBaseEntity *pEnemy = GetEnemy();
			if ( pEnemy )
			{
				Vector vecEnemyEyePos = pEnemy->EyePosition();

				float gravity = sv_gravity.GetFloat();
				if ( gravity <= 1 )
				{
					gravity = 1;
				}

				//
				// How fast does the headcrab need to travel to reach my enemy's eyes given gravity?
				//
				float height = ( vecEnemyEyePos.z - GetAbsOrigin().z );
				if ( height < 16 )
				{
					height = 16;
				}
				else if ( height > 120 )
				{
					height = 120;
				}
				float speed = sqrt( 2 * gravity * height );
				float time = speed / gravity;

				//
				// Scale the sideways velocity to get there at the right time
				//
				vecJumpDir = vecEnemyEyePos - GetAbsOrigin();
				vecJumpDir = vecJumpDir / time;

				//
				// Speed to offset gravity at the desired height.
				//
				vecJumpDir.z = speed;

				//
				// Don't jump too far/fast.
				//
				float distance = vecJumpDir.Length();
				if ( distance > 650 )
				{
					vecJumpDir = vecJumpDir * ( 650.0 / distance );
				}
			}
			else
			{
				//
				// Jump hop, don't care where.
				//
				Vector forward, up;
				AngleVectors( GetAbsAngles(), &forward, NULL, &up );
				vecJumpDir = Vector( forward.x, forward.y, up.z ) * 350;
			}

			int iSound = random->RandomInt( 0 , 1 );
			if ( iSound != 0 )
			{
				AttackSound();
			}

			SetAbsVelocity( vecJumpDir );
			m_flNextAttack = gpGlobals->curtime + 2;
			break;
		}

		default:
		{
			CAI_BaseNPC::HandleAnimEvent( pEvent );
			break;
		}
	}
}
Beispiel #15
0
void CFuncTank::TrackTarget(void)
{
	TraceResult tr;
	edict_t *   pPlayer    = FIND_CLIENT_IN_PVS(edict());
	BOOL        updateTime = FALSE, lineOfSight;
	Vector      angles, direction, targetPosition, barrelEnd;
	edict_t *   pTarget;

	// Get a position to aim for
	if(m_pController)
	{
		// Tanks attempt to mirror the player's angles
		angles         = m_pController->pev->v_angle;
		angles[0]      = 0 - angles[0];
		pev->nextthink = pev->ltime + 0.05;
	}
	else
	{
		if(IsActive())
			pev->nextthink = pev->ltime + 0.1;
		else
			return;

		if(FNullEnt(pPlayer))
		{
			if(IsActive())
				pev->nextthink = pev->ltime + 2; // Wait 2 secs
			return;
		}
		pTarget = FindTarget(pPlayer);
		if(!pTarget)
			return;

		// Calculate angle needed to aim at target
		barrelEnd      = BarrelPosition();
		targetPosition = pTarget->v.origin + pTarget->v.view_ofs;
		float range    = (targetPosition - barrelEnd).Length();

		if(!InRange(range))
			return;

		UTIL_TraceLine(barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr);

		lineOfSight = FALSE;
		// No line of sight, don't track
		if(tr.flFraction == 1.0 || tr.pHit == pTarget)
		{
			lineOfSight = TRUE;

			CBaseEntity *pInstance = CBaseEntity::Instance(pTarget);
			if(InRange(range) && pInstance && pInstance->IsAlive())
			{
				updateTime    = TRUE;
				m_sightOrigin = UpdateTargetPosition(pInstance);
			}
		}

		// Track sight origin

		// !!! I'm not sure what i changed
		direction = m_sightOrigin - pev->origin;
		//		direction = m_sightOrigin - barrelEnd;
		angles = UTIL_VecToAngles(direction);

		// Calculate the additional rotation to point the end of the barrel at the target (not the gun's center)
		AdjustAnglesForBarrel(angles, direction.Length());
	}

	angles.x = -angles.x;

	// Force the angles to be relative to the center position
	angles.y = m_yawCenter + UTIL_AngleDistance(angles.y, m_yawCenter);
	angles.x = m_pitchCenter + UTIL_AngleDistance(angles.x, m_pitchCenter);

	// Limit against range in y
	if(angles.y > m_yawCenter + m_yawRange)
	{
		angles.y   = m_yawCenter + m_yawRange;
		updateTime = FALSE; // Don't update if you saw the player, but out of range
	}
	else if(angles.y < (m_yawCenter - m_yawRange))
	{
		angles.y   = (m_yawCenter - m_yawRange);
		updateTime = FALSE; // Don't update if you saw the player, but out of range
	}

	if(updateTime)
		m_lastSightTime = gpGlobals->time;

	// Move toward target at rate or less
	float distY      = UTIL_AngleDistance(angles.y, pev->angles.y);
	pev->avelocity.y = distY * 10;
	if(pev->avelocity.y > m_yawRate)
		pev->avelocity.y = m_yawRate;
	else if(pev->avelocity.y < -m_yawRate)
		pev->avelocity.y = -m_yawRate;

	// Limit against range in x
	if(angles.x > m_pitchCenter + m_pitchRange)
		angles.x = m_pitchCenter + m_pitchRange;
	else if(angles.x < m_pitchCenter - m_pitchRange)
		angles.x = m_pitchCenter - m_pitchRange;

	// Move toward target at rate or less
	float distX      = UTIL_AngleDistance(angles.x, pev->angles.x);
	pev->avelocity.x = distX * 10;

	if(pev->avelocity.x > m_pitchRate)
		pev->avelocity.x = m_pitchRate;
	else if(pev->avelocity.x < -m_pitchRate)
		pev->avelocity.x = -m_pitchRate;

	if(m_pController)
		return;

	if(CanFire() && ((fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT)))
	{
		BOOL   fire = FALSE;
		Vector forward;
		UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL);

		if(pev->spawnflags & SF_TANK_LINEOFSIGHT)
		{
			float length = direction.Length();
			UTIL_TraceLine(barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr);
			if(tr.pHit == pTarget)
				fire = TRUE;
		}
		else
			fire = TRUE;

		if(fire)
		{
			Fire(BarrelPosition(), forward, pev);
		}
		else
			m_fireLast = 0;
	}
	else
		m_fireLast = 0;
}
Beispiel #16
0
void CLightning::StrikeThink(void)
{
	if (m_life != 0)
	{
		if (pev->spawnflags & SF_BEAM_RANDOM)
			pev->nextthink = gpGlobals->time + m_life + RANDOM_FLOAT(0, m_restrike);
		else
			pev->nextthink = gpGlobals->time + m_life + m_restrike;
	}
	m_active = 1;

	if (FStringNull(m_iszEndEntity))
	{
		if (FStringNull(m_iszStartEntity))
		{
			RandomArea();
		}
		else
		{
			CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity));
			if (pStart != NULL)
				RandomPoint(pStart->pev->origin);
			else
				ALERT(at_console, "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity));
		}
		return;
	}

	CBaseEntity *pStart = RandomTargetname(STRING(m_iszStartEntity));
	CBaseEntity *pEnd = RandomTargetname(STRING(m_iszEndEntity));

	if (pStart != NULL && pEnd != NULL)
	{
		if (IsPointEntity(pStart) || IsPointEntity(pEnd))
		{
			if (pev->spawnflags & SF_BEAM_RING)
			{
				// don't work
				return;
			}
		}

		MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
		if (IsPointEntity(pStart) || IsPointEntity(pEnd))
		{
			if (!IsPointEntity(pEnd))	// One point entity must be in pEnd
			{
				CBaseEntity *pTemp;
				pTemp = pStart;
				pStart = pEnd;
				pEnd = pTemp;
			}
			if (!IsPointEntity(pStart))	// One sided
			{
				WRITE_BYTE(TE_BEAMENTPOINT);
				WRITE_SHORT(pStart->entindex());
				WRITE_COORD(pEnd->pev->origin.x);
				WRITE_COORD(pEnd->pev->origin.y);
				WRITE_COORD(pEnd->pev->origin.z);
			}
			else
			{
				WRITE_BYTE(TE_BEAMPOINTS);
				WRITE_COORD(pStart->pev->origin.x);
				WRITE_COORD(pStart->pev->origin.y);
				WRITE_COORD(pStart->pev->origin.z);
				WRITE_COORD(pEnd->pev->origin.x);
				WRITE_COORD(pEnd->pev->origin.y);
				WRITE_COORD(pEnd->pev->origin.z);
			}
		}
		else
		{
			if (pev->spawnflags & SF_BEAM_RING)
				WRITE_BYTE(TE_BEAMRING);
			else
				WRITE_BYTE(TE_BEAMENTS);
			WRITE_SHORT(pStart->entindex());
			WRITE_SHORT(pEnd->entindex());
		}

		WRITE_SHORT(m_spriteTexture);
		WRITE_BYTE(m_frameStart); // framestart
		WRITE_BYTE((int)pev->framerate); // framerate
		WRITE_BYTE((int)(m_life*10.0)); // life
		WRITE_BYTE(m_boltWidth);  // width
		WRITE_BYTE(m_noiseAmplitude);   // noise
		WRITE_BYTE((int)pev->rendercolor.x);   // r, g, b
		WRITE_BYTE((int)pev->rendercolor.y);   // r, g, b
		WRITE_BYTE((int)pev->rendercolor.z);   // r, g, b
		WRITE_BYTE(pev->renderamt);	// brightness
		WRITE_BYTE(m_speed);		// speed
		MESSAGE_END();
		DoSparks(pStart->pev->origin, pEnd->pev->origin);
		if (pev->dmg > 0)
		{
			TraceResult tr;
			UTIL_TraceLine(pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, NULL, &tr);
			BeamDamageInstant(&tr, pev->dmg);
		}
	}
}
void CHUDAutoAim::OnThink()
{
	int wide, tall;
	GetSize( wide, tall );

	BaseClass::OnThink();

	// Get the HL2 player
	C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
	if ( pLocalPlayer == NULL )
	{
		// Just turn the autoaim crosshair off.
		ResetPosition();
		ResetAlpha();
		ResetScale();

		m_alphaFixed = 0.0f;
		return;
	}

	// Get the autoaim target.
	CBaseEntity *pTarget = pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get();

	// Fixed element stuff
	float flFixedAlphaGoal;

	if( pTarget )
	{
		flFixedAlphaGoal = hud_reticle_maxalpha.GetFloat();
	}
	else
	{
		flFixedAlphaGoal = hud_reticle_minalpha.GetFloat();
	}

	if( pLocalPlayer->m_HL2Local.m_bZooming || pLocalPlayer->m_HL2Local.m_bWeaponLowered )
	{
		flFixedAlphaGoal = 0.0f;
	}

	m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) );
	

	switch( hud_autoaim_method.GetInt() )
	{
	case AUTOAIM_METHOD_RETICLE:
		{
			if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() && pLocalPlayer->m_HL2Local.m_bStickyAutoAim )
			{
				if( !pLocalPlayer->IsInAVehicle() )
				{
					Vector vecLook;
					pLocalPlayer->EyeVectors( &vecLook, NULL, NULL );

					Vector vecMove = pLocalPlayer->GetAbsVelocity();
					float flSpeed = VectorNormalize( vecMove );
					float flDot = DotProduct( vecLook, vecMove );

					if( flSpeed >= 100 && fabs(flDot) <= 0.707f )
					{
						QAngle viewangles;
						QAngle targetangles;
						QAngle delta;

						engine->GetViewAngles( viewangles );

						Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
						VectorNormalize(vecDir);
						VectorAngles( vecDir, targetangles );

						float magnetism = hud_magnetism.GetFloat();

						delta[0] = ApproachAngle( targetangles[0], viewangles[0], magnetism );
						delta[1] = ApproachAngle( targetangles[1], viewangles[1], magnetism );
						delta[2] = targetangles[2];

						//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
						engine->SetViewAngles( delta );
					}
				}
			}

#if 0
			bool doScaling = hud_autoaim_scale_icon.GetBool();

			// These are the X & Y coords of where the crosshair should be. Default to 
			// returning to the center of the screen if there is no target.
			int goalx = ScreenWidth() / 2;
			int goaly = ScreenHeight() / 2;
			int goalalpha = 0;
			float goalscale = AUTOAIM_MIN_SCALE;
			float speed = AUTOAIM_OFFTARGET_CROSSHAIR_SPEED;

			if( pTarget )
			{
				// Get the autoaim crosshair onto the target.
				Vector screen;

				// Center the crosshair on the entity.
				if( doScaling )
				{
					// Put the crosshair over the center of the target.
					ScreenTransform( pTarget->WorldSpaceCenter(), screen );
				}
				else
				{
					// Put the crosshair exactly where the player is aiming.
					ScreenTransform( pLocalPlayer->m_HL2Local.m_vecAutoAimPoint, screen );
				}

				// Set Goal Position and speed.
				goalx += 0.5f * screen[0] * ScreenWidth() + 0.5f;
				goaly -= 0.5f * screen[1] * ScreenHeight() + 0.5f;
				speed = AUTOAIM_ONTARGET_CROSSHAIR_SPEED;

				goalalpha = AUTOAIM_MAX_ALPHA;

				if( doScaling )
				{
					// Scale the crosshair to envelope the entity's bounds on screen.
					Vector vecMins, vecMaxs;
					Vector vecScreenMins, vecScreenMaxs;

					// Get mins and maxs in world space
					vecMins = pTarget->GetAbsOrigin() + pTarget->WorldAlignMins();
					vecMaxs = pTarget->GetAbsOrigin() + pTarget->WorldAlignMaxs();

					// Project them to screen
					ScreenTransform( vecMins, vecScreenMins );
					ScreenTransform( vecMaxs, vecScreenMaxs );

					vecScreenMins.y = (ScreenWidth()/2) - 0.5f * vecScreenMins.y * ScreenWidth() + 0.5f;
					vecScreenMaxs.y = (ScreenWidth()/2) - 0.5f * vecScreenMaxs.y * ScreenWidth() + 0.5f;

					float screenSize = vecScreenMins.y - vecScreenMaxs.y;

					// Set goal scale
					goalscale = screenSize / 64.0f; // 64 is the width of the crosshair art.
				}
				else
				{
					goalscale = 1.0f;
				}
			}

			// Now approach the goal, alpha, and scale
			Vector vecGoal( goalx, goaly, 0 );
			Vector vecDir = vecGoal - m_vecPos;
			float flDistRemaining = VectorNormalize( vecDir );
			m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) );

			// Lerp and Clamp scale
			float scaleDelta = fabs( goalscale - m_scale );
			float scaleMove = min( AUTOAIM_SCALE_SPEED * gpGlobals->frametime, scaleDelta );
			if( m_scale < goalscale )
			{
				m_scale += scaleMove;
			}
			else if( m_scale > goalscale )
			{
				m_scale -= scaleMove;
			}
			if( m_scale > AUTOAIM_MAX_SCALE )
			{
				m_scale = AUTOAIM_MAX_SCALE;
			}
			else if( m_scale < AUTOAIM_MIN_SCALE )
			{
				m_scale = AUTOAIM_MIN_SCALE;
			}

			if( goalalpha > m_alpha )
			{
				m_alpha += AUTOAIM_ALPHA_UP_SPEED * gpGlobals->frametime;
			}
			else if( goalalpha < m_alpha )
			{
				m_alpha -= AUTOAIM_ALPHA_DOWN_SPEED * gpGlobals->frametime;
			}

			// Clamp alpha
			if( m_alpha < 0 )
			{
				m_alpha = 0;
			}
			else if( m_alpha > AUTOAIM_MAX_ALPHA )
			{
				m_alpha = AUTOAIM_MAX_ALPHA;
			}
#endif
		}
		break;

	case AUTOAIM_METHOD_DRIFT:
		{
			if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
			{
				QAngle viewangles;

				engine->GetViewAngles( viewangles );
				
				Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
				VectorNormalize(vecDir);

				VectorAngles( vecDir, viewangles );

				//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
				engine->SetViewAngles( viewangles );
			}
		}
		break;
	}
}
// bayonet attack
void CBaseBayonet::SecondaryAttack( void )
{
	if(m_pPlayer->pev->flags & FL_DUCKING || m_pPlayer->pev->button & IN_DUCK)
		return;

	//BP to prevent players from stabbing right after getting up
	if(m_fNextStabTime > UTIL_WeaponTimeBase())
		return;

	SetWeaponDamage(pData->flSecondaryDmgModifier);

	TraceResult tr;


	UTIL_MakeVectors(m_pPlayer->pev->v_angle);
	Vector vecSrc	= m_pPlayer->GetGunPosition();
	Vector vecEnd	= vecSrc + gpGlobals->v_forward * this->pData->flBladeLength;

	UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT( m_pPlayer->pev ), &tr );

#ifndef CLIENT_DLL
	CBaseEntity *pHit = NULL;
/*	if ( tr.flFraction >= 1.0 )
	{
		UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT( m_pPlayer->pev ), &tr );
		if ( tr.flFraction < 1.0 )
		{
			// Calculate the point of intersection of the line (or hull) and the object we hit
			// This is and approximation of the "best" intersection
			pHit = CBaseEntity::Instance( tr.pHit );
			if ( !pHit || pHit->IsBSPModel() )
			{
				FindHullIntersection( vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict() );
			}
			vecEnd = tr.vecEndPos;	// This is the point on the actual surface (the hull could have hit space)
		}
	}*/

	if(tr.flFraction < 1.0)
	{
		pHit = CBaseEntity::Instance( tr.pHit );

		if (pHit && pHit->pev->takedamage)
		{
			float flDamage = m_pPlayer->GetDamage(m_pPlayer->pev, gpGlobals->v_forward, &tr);

			if(pHit->IsPlayer())
			{
				Vector vecOrg = tr.vecEndPos - gpGlobals->v_forward * 4;

				if ( g_pGameRules->FPlayerCanTakeDamage( m_pPlayer, pHit ) && flDamage != 0.0)
				{
					pev->classname = MAKE_STRING("weapon_Bayonet");
					ClearMultiDamage( );
					pHit->TraceAttack(m_pPlayer->pev, flDamage, gpGlobals->v_forward, &tr, DMG_CLUB | DMG_NEVERGIB ); 
					
					pev->iuser3 = tr.iHitgroup; // hack to get the hitgroup used

					ApplyMultiDamage( pev, m_pPlayer->pev );
					EMIT_SOUND(ENT(pev), CHAN_WEAPON, pData->snd_hit, 1, ATTN_NORM);
					SpawnBlood( vecOrg, BLOOD_COLOR_RED, flDamage * 4 ); // Make a lot of Blood!
				}
			}
			else
			{
				ClearMultiDamage( );
				pHit->TraceAttack(m_pPlayer->pev, flDamage, gpGlobals->v_forward, &tr, DMG_CLUB | DMG_NEVERGIB ); 
				ApplyMultiDamage( pev, m_pPlayer->pev );
			}
		}
		else
		{
			if(pData->snd_hitwall)
				EMIT_SOUND(ENT(pev), CHAN_AUTO, pData->snd_hitwall, 1, ATTN_NORM);
	
			DecalGunshot( &tr, BULLET_BLADE );
		}
	}

#endif
	m_pPlayer->SetAnimation( PLAYER_BAYONET );

	int flags;
#if defined( CLIENT_WEAPONS )
	flags = FEV_NOTHOST;
#else
	flags = 0;
#endif
	int iIsEmpty = (m_iClip > 0 ? 0 : 1);

	// use event secondary so that the bayonet weapons can use there events
	// melee weapons can use the same event for primary and secondary
	PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), pData->m_usSecondaryAttack, 0.0, m_pPlayer->pev->origin, m_pPlayer->pev->angles, 0.0, 0, m_pPlayer->pev->team, m_iId, iIsEmpty, 0 );
	m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + pData->flAttackDelay;
	m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + pData->flAttackDelay;
	m_pPlayer->BurnStamina(MAX_STAMINA / 5, (float)0.1);
}
Beispiel #19
0
void SpawnAllEntities( int nEntities, HierarchicalSpawn_t *pSpawnList, bool bActivateEntities )
{
#if !defined( _RETAIL )
#if defined( _XBOX )
	char sz[ 128 ];
	Q_snprintf( sz, sizeof( sz ), "SpawnAllEntities(%d)", nEntities );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif

	int nEntity;
	for (nEntity = 0; nEntity < nEntities; nEntity++)
	{
		VPROF( "MapEntity_ParseAllEntities_Spawn");
		CBaseEntity *pEntity = pSpawnList[nEntity].m_pEntity;

		if ( pEntity )
		{
			if (DispatchSpawn(pEntity) < 0)
			{
				for ( int i = nEntity+1; i < nEntities; i++ )
				{
					// this is a child object that will be deleted now
					if ( pSpawnList[i].m_pEntity && pSpawnList[i].m_pEntity->IsMarkedForDeletion() )
					{
						pSpawnList[i].m_pEntity = NULL;
					}
				}
				// Spawn failed.
				gEntList.CleanupDeleteList();
				// Remove the entity from the spawn list
				pSpawnList[nEntity].m_pEntity = NULL;
			}
		}
	}

#if !defined( _RETAIL )
#if defined( _XBOX )
	Q_snprintf( sz, sizeof( sz ), "SpawnAllEntities(%d) -activate", nEntities );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif
	if ( bActivateEntities )
	{
		VPROF( "MapEntity_ParseAllEntities_Activate");
		bool bAsyncAnims = mdlcache->SetAsyncLoad( MDLCACHE_ANIMBLOCK, false );
		for (nEntity = 0; nEntity < nEntities; nEntity++)
		{
			CBaseEntity *pEntity = pSpawnList[nEntity].m_pEntity;

			if ( pEntity )
			{
				MDLCACHE_CRITICAL_SECTION();
				pEntity->Activate();
			}
		}
		mdlcache->SetAsyncLoad( MDLCACHE_ANIMBLOCK, bAsyncAnims );
	}
#if !defined( _RETAIL )
#if defined( _XBOX )
	Q_snprintf( sz, sizeof( sz ), "SpawnAllEntities(%d) -done activating", nEntities );
	XBX_rTimeStampLog( Plat_FloatTime(), sz );
#endif
#endif
}
Beispiel #20
0
//=========================================================
//=========================================================
void CBarnacle :: BarnacleThink ( void )
{
	CBaseEntity *pTouchEnt;
	CBaseMonster *pVictim;
	float flLength;

	pev->nextthink = gpGlobals->time + 0.1;

	if ( m_hEnemy != NULL )
	{
// barnacle has prey.

		if ( !m_hEnemy->IsAlive() )
		{
			// someone (maybe even the barnacle) killed the prey. Reset barnacle.
			m_fLiftingPrey = FALSE;// indicate that we're not lifting prey.
			m_hEnemy = NULL;
			return;
		}

		if ( m_fLiftingPrey )
		{
			if ( m_hEnemy != NULL && m_hEnemy->pev->deadflag != DEAD_NO )
			{
				// crap, someone killed the prey on the way up.
				m_hEnemy = NULL;
				m_fLiftingPrey = FALSE;
				return;
			}

	// still pulling prey.
			Vector vecNewEnemyOrigin = m_hEnemy->pev->origin;
			vecNewEnemyOrigin.x = pev->origin.x;
			vecNewEnemyOrigin.y = pev->origin.y;

			// guess as to where their neck is
			vecNewEnemyOrigin.x -= 6 * cos(m_hEnemy->pev->angles.y * M_PI/180.0);	
			vecNewEnemyOrigin.y -= 6 * sin(m_hEnemy->pev->angles.y * M_PI/180.0);

			m_flAltitude -= BARNACLE_PULL_SPEED;
			vecNewEnemyOrigin.z += BARNACLE_PULL_SPEED;

			if ( fabs( pev->origin.z - ( vecNewEnemyOrigin.z + m_hEnemy->pev->view_ofs.z - 8 ) ) < BARNACLE_BODY_HEIGHT )
			{
		// prey has just been lifted into position ( if the victim origin + eye height + 8 is higher than the bottom of the barnacle, it is assumed that the head is within barnacle's body )
				m_fLiftingPrey = FALSE;

				EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_bite3.wav", 1, ATTN_NORM );	

				pVictim = m_hEnemy->MyMonsterPointer();

				m_flKillVictimTime = gpGlobals->time + 10;// now that the victim is in place, the killing bite will be administered in 10 seconds.

				if ( pVictim )
				{
					pVictim->BarnacleVictimBitten( pev );
					SetActivity ( ACT_EAT );
				}
			}

			UTIL_SetOrigin ( m_hEnemy->pev, vecNewEnemyOrigin );
		}
		else
		{
	// prey is lifted fully into feeding position and is dangling there.

			pVictim = m_hEnemy->MyMonsterPointer();

			if ( m_flKillVictimTime != -1 && gpGlobals->time > m_flKillVictimTime )
			{
				// kill!
				if ( pVictim )
				{
					pVictim->TakeDamage ( pev, pev, pVictim->pev->health, DMG_SLASH | DMG_ALWAYSGIB );
					m_cGibs = 3;
				}

				return;
			}

			// bite prey every once in a while
			if ( pVictim && ( RANDOM_LONG(0,49) == 0 ) )
			{
				switch ( RANDOM_LONG(0,2) )
				{
				case 0:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM );	break;
				case 1:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM );	break;
				case 2:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM );	break;
				}

				pVictim->BarnacleVictimBitten( pev );
			}

		}
	}
	else
	{
// barnacle has no prey right now, so just idle and check to see if anything is touching the tongue.

		// If idle and no nearby client, don't think so often
		if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
			pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5);	// Stagger a bit to keep barnacles from thinking on the same frame

		if ( m_fSequenceFinished )
		{// this is done so barnacle will fidget.
			SetActivity ( ACT_IDLE );
			m_flTongueAdj = -100;
		}

		if ( m_cGibs && RANDOM_LONG(0,99) == 1 )
		{
			// cough up a gib.
			CGib::SpawnRandomGibs( pev, 1, 1 );
			m_cGibs--;

			switch ( RANDOM_LONG(0,2) )
			{
			case 0:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM );	break;
			case 1:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM );	break;
			case 2:	EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM );	break;
			}
		}

		pTouchEnt = TongueTouchEnt( &flLength );

		if ( pTouchEnt != NULL && m_fTongueExtended )
		{
			// tongue is fully extended, and is touching someone.
			if ( pTouchEnt->FBecomeProne() )
			{
				EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_alert2.wav", 1, ATTN_NORM );	

				SetSequenceByName ( "attack1" );
				m_flTongueAdj = -20;

				m_hEnemy = pTouchEnt;

				pTouchEnt->pev->movetype = MOVETYPE_FLY;
				pTouchEnt->pev->velocity = g_vecZero;
				pTouchEnt->pev->basevelocity = g_vecZero;
				pTouchEnt->pev->origin.x = pev->origin.x;
				pTouchEnt->pev->origin.y = pev->origin.y;

				m_fLiftingPrey = TRUE;// indicate that we should be lifting prey.
				m_flKillVictimTime = -1;// set this to a bogus time while the victim is lifted.

				m_flAltitude = (pev->origin.z - pTouchEnt->EyePosition().z);
			}
		}
		else
		{
			// calculate a new length for the tongue to be clear of anything else that moves under it. 
			if ( m_flAltitude < flLength )
			{
				// if tongue is higher than is should be, lower it kind of slowly.
				m_flAltitude += BARNACLE_PULL_SPEED;
				m_fTongueExtended = FALSE;
			}
			else
			{
				m_flAltitude = flLength;
				m_fTongueExtended = TRUE;
			}

		}

	}

	// ALERT( at_console, "tounge %f\n", m_flAltitude + m_flTongueAdj );
	SetBoneController( 0, -(m_flAltitude + m_flTongueAdj) );
	StudioFrameAdvance( 0.1 );
}
Beispiel #21
0
//=========================================================
//=========================================================
void CHalfLifeTeamplay::RecountTeams( void )
{
    char	*pName;
    char	teamlist[TEAMPLAY_TEAMLISTLENGTH];

    // loop through all teams, recounting everything
    num_teams = 0;

    // Copy all of the teams from the teamlist
    // make a copy because strtok is destructive
    strcpy( teamlist, m_szTeamList );
    pName = teamlist;
    pName = strtok( pName, ";" );
    while ( pName != NULL && *pName )
    {
        if ( GetTeamIndex( pName ) < 0 )
        {
            strcpy( team_names[num_teams], pName );
            num_teams++;
        }
        pName = strtok( NULL, ";" );
    }

    if ( num_teams < 2 )
    {
        num_teams = 0;
        m_teamLimit = FALSE;
    }

    // Sanity check
    memset( team_scores, 0, sizeof(team_scores) );

    // loop through all clients
    for ( int i = 1; i <= gpGlobals->maxClients; i++ )
    {
        CBaseEntity *plr = UTIL_PlayerByIndex( i );

        if ( plr )
        {
            const char *pTeamName = plr->TeamID();
            // try add to existing team
            int tm = GetTeamIndex( pTeamName );

            if ( tm < 0 ) // no team match found
            {
                if ( !m_teamLimit )
                {
                    // add to new team
                    tm = num_teams;
                    num_teams++;
                    team_scores[tm] = 0;
                    strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH );
                }
            }

            if ( tm >= 0 )
            {
                team_scores[tm] += static_cast<int>(plr->pev->frags);
            }
        }
    }
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//
// Returns number of events handled, 0 if none.
//=========================================================
void CBigMomma :: HandleAnimEvent( MonsterEvent_t *pEvent )
{
	switch( pEvent->event )
	{
		case BIG_AE_MELEE_ATTACKBR:
		case BIG_AE_MELEE_ATTACKBL:
		case BIG_AE_MELEE_ATTACK1:
		{
			Vector forward, right;

			UTIL_MakeVectorsPrivate( pev->angles, forward, right, NULL );

			Vector center = pev->origin + forward * 128;
			Vector mins = center - Vector( 64, 64, 0 );
			Vector maxs = center + Vector( 64, 64, 64 );

			CBaseEntity *pList[8];
			int count = UTIL_EntitiesInBox( pList, 8, mins, maxs, FL_MONSTER|FL_CLIENT );
			CBaseEntity *pHurt = NULL;

			for ( int i = 0; i < count && !pHurt; i++ )
			{
				if ( pList[i] != this )
				{
					if ( pList[i]->pev->owner != edict() )
						pHurt = pList[i];
				}
			}
					
			if ( pHurt )
			{
				pHurt->TakeDamage( pev, pev, gSkillData.bigmommaDmgSlash, DMG_CRUSH | DMG_SLASH );
				pHurt->pev->punchangle.x = 15;
				switch( pEvent->event )
				{
					case BIG_AE_MELEE_ATTACKBR:
						pHurt->pev->velocity = pHurt->pev->velocity + (forward * 150) + Vector(0,0,250) - (right * 200);
					break;

					case BIG_AE_MELEE_ATTACKBL:
						pHurt->pev->velocity = pHurt->pev->velocity + (forward * 150) + Vector(0,0,250) + (right * 200);
					break;

					case BIG_AE_MELEE_ATTACK1:
						pHurt->pev->velocity = pHurt->pev->velocity + (forward * 220) + Vector(0,0,200);
					break;
				}

				pHurt->pev->flags &= ~FL_ONGROUND;
				EMIT_SOUND_DYN( edict(), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pAttackHitSounds), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
			}
		}
		break;
		
		case BIG_AE_SCREAM:
			EMIT_SOUND_ARRAY_DYN( CHAN_VOICE, pAlertSounds );
			break;
		
		case BIG_AE_PAIN_SOUND:
			EMIT_SOUND_ARRAY_DYN( CHAN_VOICE, pPainSounds );
			break;
		
		case BIG_AE_ATTACK_SOUND:
			EMIT_SOUND_ARRAY_DYN( CHAN_WEAPON, pAttackSounds );
			break;

		case BIG_AE_BIRTH_SOUND:
			EMIT_SOUND_ARRAY_DYN( CHAN_BODY, pBirthSounds );
			break;

		case BIG_AE_SACK:
			if ( RANDOM_LONG(0,100) < 30 )
				EMIT_SOUND_ARRAY_DYN( CHAN_BODY, pSackSounds );
			break;

		case BIG_AE_DEATHSOUND:
			EMIT_SOUND_ARRAY_DYN( CHAN_VOICE, pDeathSounds );
			break;

		case BIG_AE_STEP1:		// Footstep left
		case BIG_AE_STEP3:		// Footstep back left
			EMIT_SOUND_ARRAY_DYN( CHAN_ITEM, pFootSounds );
			break;

		case BIG_AE_STEP4:		// Footstep back right
		case BIG_AE_STEP2:		// Footstep right
			EMIT_SOUND_ARRAY_DYN( CHAN_BODY, pFootSounds );
			break;

		case BIG_AE_MORTAR_ATTACK1:
			LaunchMortar();
			break;

		case BIG_AE_LAY_CRAB:
			LayHeadcrab();
			break;

		case BIG_AE_JUMP_FORWARD:
			ClearBits( pev->flags, FL_ONGROUND );

			UTIL_SetOrigin (this, pev->origin + Vector ( 0 , 0 , 1) );// take her off ground so engine doesn't instantly reset onground 
			UTIL_MakeVectors ( pev->angles );

			pev->velocity = (gpGlobals->v_forward * 200) + gpGlobals->v_up * 500;
			break;

		case BIG_AE_EARLY_TARGET:
			{
				CBaseEntity *pTarget = m_hTargetEnt;
				if ( pTarget && pTarget->pev->message )
					FireTargets( STRING(pTarget->pev->message), this, this, USE_TOGGLE, 0 );
				Remember( bits_MEMORY_FIRED_NODE );
			}
			break;

		default:
			CBaseMonster::HandleAnimEvent( pEvent );
			break;
	}
}
Beispiel #23
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_LeadBehavior::GatherConditions(void)
{
    BaseClass::GatherConditions();

    if (HasGoal())
    {
        // Fix for bad transition case (to investigate)
        if ((WorldSpaceCenter() - m_goal).LengthSqr() > (64 * 64) && IsCurSchedule(SCHED_LEAD_AWAIT_SUCCESS, false))
        {
            GetOuter()->ClearSchedule("Lead behavior - bad transition?");
        }

        // We have to collect data about the person we're leading around.
        CBaseEntity *pFollower = AI_GetSinglePlayer();

        if (pFollower)
        {
            ClearCondition(COND_LEAD_FOLLOWER_VERY_CLOSE);
            ClearCondition(COND_LEAD_FOLLOWER_MOVING_TOWARDS_ME);

            // Check distance to the follower
            float flFollowerDist = (WorldSpaceCenter() - pFollower->WorldSpaceCenter()).Length();
            bool bLagging = flFollowerDist > (m_leaddistance * 4);
            if (bLagging)
            {
                if (PlayerIsAheadOfMe())
                {
                    bLagging = false;
                }
            }

            // Player heading towards me?
            // Only factor this in if you're not too far from them
            if (flFollowerDist < (m_leaddistance * 4))
            {
                Vector vecVelocity = pFollower->GetSmoothedVelocity();
                if (VectorNormalize(vecVelocity) > 50)
                {
                    Vector vecToPlayer = (GetAbsOrigin() - pFollower->GetAbsOrigin());
                    VectorNormalize(vecToPlayer);
                    if (DotProduct(vecVelocity, vecToPlayer) > 0.5)
                    {
                        SetCondition(COND_LEAD_FOLLOWER_MOVING_TOWARDS_ME);
                        bLagging = false;
                    }
                }
            }

            // If he's outside our lag range, consider him lagging
            if (bLagging)
            {
                SetCondition(COND_LEAD_FOLLOWER_LAGGING);
                ClearCondition(COND_LEAD_FOLLOWER_NOT_LAGGING);
            }
            else
            {
                ClearCondition(COND_LEAD_FOLLOWER_LAGGING);
                SetCondition(COND_LEAD_FOLLOWER_NOT_LAGGING);

                // If he's really close, note that
                if (flFollowerDist < m_leaddistance)
                {
                    SetCondition(COND_LEAD_FOLLOWER_VERY_CLOSE);
                }
            }

            // To be considered not lagging, the follower must be visible, and within the lead distance
            if (GetOuter()->FVisible(pFollower) && GetOuter()->GetSenses()->ShouldSeeEntity(pFollower))
            {
                SetCondition(COND_LEAD_HAVE_FOLLOWER_LOS);
                m_LostLOSTimer.Stop();
            }
            else
            {
                ClearCondition(COND_LEAD_HAVE_FOLLOWER_LOS);

                // We don't have a LOS. But if we did have LOS, don't clear it until the timer is up.
                if (m_LostLOSTimer.IsRunning())
                {
                    if (m_LostLOSTimer.Expired())
                    {
                        SetCondition(COND_LEAD_FOLLOWER_LAGGING);
                        ClearCondition(COND_LEAD_FOLLOWER_NOT_LAGGING);
                    }
                }
                else
                {
                    m_LostLOSTimer.Start();
                }
            }

            // Now we want to see if the follower is lost. Being lost means being (far away || out of LOS ) 
            // && some time has passed. Also, lagging players are considered lost if the NPC's never delivered
            // the start speech, because it means the NPC should run to the player to start the lead.
            if (HasCondition(COND_LEAD_FOLLOWER_LAGGING))
            {
                if (!m_hasspokenstart)
                {
                    SetCondition(COND_LEAD_FOLLOWER_LOST);
                }
                else
                {
                    if (m_args.bStopScenesWhenPlayerLost)
                    {
                        // Try and stop me speaking my monolog, if I am
                        if (!m_hasPausedScenes && IsRunningScriptedScene(GetOuter()))
                        {
                            //Msg("Stopping scenes.\n");
                            PauseActorsScriptedScenes(GetOuter(), false);
                            m_hasPausedScenes = true;
                        }
                    }

                    if (m_LostTimer.IsRunning())
                    {
                        if (m_LostTimer.Expired())
                        {
                            SetCondition(COND_LEAD_FOLLOWER_LOST);
                        }
                    }
                    else
                    {
                        m_LostTimer.Start();
                    }
                }
            }
            else
            {
                // If I was speaking a monolog, resume it
                if (m_args.bStopScenesWhenPlayerLost && m_hasPausedScenes)
                {
                    if (IsRunningScriptedScene(GetOuter()))
                    {
                        //Msg("Resuming scenes.\n");
                        ResumeActorsScriptedScenes(GetOuter(), false);
                    }

                    m_hasPausedScenes = false;
                }

                m_LostTimer.Stop();
                ClearCondition(COND_LEAD_FOLLOWER_LOST);
            }

            // Evaluate for success
            // Success right now means being stationary, close to the goal, and having the player close by
            if (!(m_args.flags & AILF_NO_DEF_SUCCESS))
            {
                ClearCondition(COND_LEAD_SUCCESS);

                // Check Z first, and only check 2d if we're within that
                bool bWithinZ = fabs(GetLocalOrigin().z - m_goal.z) < 64;
                if (bWithinZ && (GetLocalOrigin() - m_goal).Length2D() <= 64)
                {
                    if (HasCondition(COND_LEAD_FOLLOWER_VERY_CLOSE))
                    {
                        SetCondition(COND_LEAD_SUCCESS);
                    }
                    else if (m_successdistance)
                    {
                        float flDistSqr = (pFollower->GetAbsOrigin() - GetLocalOrigin()).Length2DSqr();
                        if (flDistSqr < (m_successdistance*m_successdistance))
                        {
                            SetCondition(COND_LEAD_SUCCESS);
                        }
                    }
                }
            }
            if (m_MoveMonitor.IsMarkSet() && m_MoveMonitor.TargetMoved(pFollower))
                SetCondition(COND_LEAD_FOLLOWER_MOVED_FROM_MARK);
            else
                ClearCondition(COND_LEAD_FOLLOWER_MOVED_FROM_MARK);
        }
    }

    if (m_args.bLeadDuringCombat)
    {
        ClearCondition(COND_LIGHT_DAMAGE);
        ClearCondition(COND_HEAVY_DAMAGE);
    }
}
Beispiel #24
0
	// Regular explosions
	void CPlantedC4::Explode( trace_t *pTrace, int bitsDamageType )
	{
		// Check to see if the round is over after the bomb went off...
		CSGameRules()->m_bTargetBombed = true;
		m_bBombTicking = false;
		CSGameRules()->CheckWinConditions();

		// Do the Damage
		float flBombRadius = 500;
		if ( g_pMapInfo )
			flBombRadius = g_pMapInfo->m_flBombRadius;

		// Output to the bomb target ent
		CBaseEntity *pTarget = NULL;
		variant_t emptyVariant;
		while ((pTarget = gEntList.FindEntityByClassname( pTarget, "func_bomb_target" )) != NULL)
		{
			//Adrian - But only to the one we want!
			if ( pTarget->entindex() != m_iBombSiteIndex )
				 continue;
			
			pTarget->AcceptInput( "BombExplode", this, this, emptyVariant, 0 );
				break;
		}	

		// Pull out of the wall a bit
		if ( pTrace->fraction != 1.0 )
		{
			SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) );
		}

		{
			Vector pos = GetAbsOrigin() + Vector( 0,0,8 );

			// add an explosion TE so it affects clientside physics
			CPASFilter filter( pos );
			te->Explosion( filter, 0.0,
				&pos, 
				g_sModelIndexFireball,
				50.0, 
				25,
				TE_EXPLFLAG_NONE,
				flBombRadius * 3.5,
				200 );
		}
		
		// Fireball sprite and sound!!
		{
			Vector fireballPos = GetAbsOrigin();
			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		{
			Vector fireballPos = GetAbsOrigin() + Vector( 
				random->RandomFloat( -512, 512 ), 
				random->RandomFloat( -512, 512 ),
				random->RandomFloat( -10, 10 ) );

			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		{
			Vector fireballPos = GetAbsOrigin() + Vector( 
				random->RandomFloat( -512, 512 ), 
				random->RandomFloat( -512, 512 ),
				random->RandomFloat( -10, 10 ) );

			CPVSFilter filter( fireballPos );
			te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 );
		}

		// Sound! for everyone
		CBroadcastRecipientFilter filter;
		EmitSound( filter, entindex(), "c4.explode" );


		// Decal!
		UTIL_DecalTrace( pTrace, "Scorch" );

		
		// Shake!
		UTIL_ScreenShake( pTrace->endpos, 25.0, 150.0, 1.0, 3000, SHAKE_START );


		SetOwnerEntity( NULL ); // can't traceline attack owner if this is set

		CSGameRules()->RadiusDamage( 
			CTakeDamageInfo( this, GetOwnerEntity(), flBombRadius, bitsDamageType ),
			GetAbsOrigin(),
			flBombRadius * 3.5,	//Matt - don't ask me, this is how CS does it.
			CLASS_NONE,
			true );	// IGNORE THE WORLD!!

		// send director message, that something important happed here
		/*
		MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR );
			WRITE_BYTE ( 9 );	// command length in bytes
			WRITE_BYTE ( DRC_CMD_EVENT );	// bomb explode
			WRITE_SHORT( ENTINDEX(this->edict()) );	// index number of primary entity
			WRITE_SHORT( 0 );	// index number of secondary entity
			WRITE_LONG( 15 | DRC_FLAG_FINAL );   // eventflags (priority and flags)
		MESSAGE_END();
		*/

		UTIL_Remove( this );
	}
Beispiel #25
0
//-----------------------------------------------------------------------------
// Purpose: Handles USE keypress
//-----------------------------------------------------------------------------
void CBasePlayer::PlayerUse ( void )
{
#ifdef GAME_DLL
	// Was use pressed or released?
	if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) )
		return;

	if ( IsObserver() )
	{
		// do special use operation in oberserver mode
		if ( m_afButtonPressed & IN_USE )
			ObserverUse( true );
		else if ( m_afButtonReleased & IN_USE )
			ObserverUse( false );
		
		return;
	}

#if !defined(_XBOX)
	// push objects in turbo physics mode
	if ( (m_nButtons & IN_USE) && sv_turbophysics.GetBool() )
	{
		Vector forward, up;
		EyeVectors( &forward, NULL, &up );

		trace_t tr;
		// Search for objects in a sphere (tests for entities that are not solid, yet still useable)
		Vector searchCenter = EyePosition();

		CUsePushFilter filter;

		UTIL_TraceLine( searchCenter, searchCenter + forward * 96.0f, MASK_SOLID, &filter, &tr );

		// try the hit entity if there is one, or the ground entity if there isn't.
		CBaseEntity *entity = tr.m_pEnt;

		if ( entity )
		{
			IPhysicsObject *pObj = entity->VPhysicsGetObject();

			if ( pObj )
			{
				Vector vPushAway = (entity->WorldSpaceCenter() - WorldSpaceCenter());
				vPushAway.z = 0;

				float flDist = VectorNormalize( vPushAway );
				flDist = MAX( flDist, 1 );

				float flForce = sv_pushaway_force.GetFloat() / flDist;
				flForce = MIN( flForce, sv_pushaway_max_force.GetFloat() );

				pObj->ApplyForceOffset( vPushAway * flForce, WorldSpaceCenter() );
			}
		}
	}
#endif

	if ( m_afButtonPressed & IN_USE )
	{
		// Controlling some latched entity?
		if ( ClearUseEntity() )
		{
			return;
		}
		else
		{
			if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )
			{
				m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;
				m_iTrain = TRAIN_NEW|TRAIN_OFF;
				return;
			}
			else
			{	// Start controlling the train!
				CBaseEntity *pTrain = GetGroundEntity();
				if ( pTrain && !(m_nButtons & IN_JUMP) && (GetFlags() & FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(this) )
				{
					m_afPhysicsFlags |= PFLAG_DIROVERRIDE;
					m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed());
					m_iTrain |= TRAIN_NEW;
					EmitSound( "Player.UseTrain" );
					return;
				}
			}
		}
	}

	CBaseEntity *pUseEntity = FindUseEntity();

	// Found an object
	if ( pUseEntity )
	{

		//!!!UNDONE: traceline here to prevent +USEing buttons through walls			

		int caps = pUseEntity->ObjectCaps();
		variant_t emptyVariant;
		if ( ( (m_nButtons & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) || ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) )
		{
			if ( caps & FCAP_CONTINUOUS_USE )
			{
				m_afPhysicsFlags |= PFLAG_USING;
			}

			if ( pUseEntity->ObjectCaps() & FCAP_ONOFF_USE )
			{
				pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_ON );
			}
			else
			{
				pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );
			}
		}
		// UNDONE: Send different USE codes for ON/OFF.  Cache last ONOFF_USE object to send 'off' if you turn away
		else if ( (m_afButtonReleased & IN_USE) && (pUseEntity->ObjectCaps() & FCAP_ONOFF_USE) )	// BUGBUG This is an "off" use
		{
			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_OFF );
		}
	}
	else if ( m_afButtonPressed & IN_USE )
	{
		PlayUseDenySound();
	}
#endif
}
Beispiel #26
0
void CC4::PrimaryAttack()
{
	bool	PlaceBomb = false;
	CCSPlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

	int onGround = FBitSet( pPlayer->GetFlags(), FL_ONGROUND );
	CBaseEntity *groundEntity = (onGround) ? pPlayer->GetGroundEntity() : NULL;
	if ( groundEntity )
	{
		// Don't let us stand on players, breakables, or pushaway physics objects to plant
		if ( groundEntity->IsPlayer() ||
			IsPushableEntity( groundEntity ) ||
#ifndef CLIENT_DLL
			IsBreakableEntity( groundEntity ) ||
#endif // !CLIENT_DLL
			IsPushAwayEntity( groundEntity ) )
		{
			onGround = false;
		}
	}

	if( m_bStartedArming == false && m_bBombPlanted == false )
	{
		if( pPlayer->m_bInBombZone && onGround )
		{
			m_bStartedArming = true;
			m_fArmedTime = gpGlobals->curtime + WEAPON_C4_ARM_TIME;
			m_bBombPlacedAnimation = false;


#if !defined( CLIENT_DLL )			
			// init the beep flags
			int i;
			for( i=0;i<NUM_BEEPS;i++ )
				m_bPlayedArmingBeeps[i] = false;

			// freeze the player in place while planting
			pPlayer->SetMaxSpeed( 1 );

			// player "arming bomb" animation
			pPlayer->SetAnimation( PLAYER_ATTACK1 );
	
			pPlayer->SetNextAttack( gpGlobals->curtime );

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beginplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}
#endif

			SendWeaponAnim( ACT_VM_PRIMARYATTACK );

			FX_PlantBomb( pPlayer->entindex(), pPlayer->Weapon_ShootPosition() );
		}
		else
		{
			if ( !pPlayer->m_bInBombZone )
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot");
			}
			else
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground");
			}

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
			return;
		}
	}
	else
	{
		if ( !onGround || !pPlayer->m_bInBombZone )
		{
			if( !pPlayer->m_bInBombZone )
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Arming_Cancelled" );
			}
			else
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground" );
			}

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.5;
			m_bStartedArming = false;

#if !defined( CLIENT_DLL )
			// release the player from being frozen, we've somehow left the bomb zone
			pPlayer->ResetMaxSpeed();

			pPlayer->SetProgressBarTime( 0 );

			//pPlayer->SetAnimation( PLAYER_HOLDBOMB );

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}

#endif
			if(m_bBombPlacedAnimation == true) //this means the placement animation is canceled
			{
				SendWeaponAnim( ACT_VM_DRAW );
			}
			else
			{
				SendWeaponAnim( ACT_VM_IDLE );
			}
			
			return;
		}
		else
		{
#ifndef CLIENT_DLL
			PlayArmingBeeps();
#endif

			if( gpGlobals->curtime >= m_fArmedTime ) //the c4 is ready to be armed
			{
				//check to make sure the player is still in the bomb target area
				PlaceBomb = true;
			}
			else if( ( gpGlobals->curtime >= (m_fArmedTime - 0.75) ) && ( !m_bBombPlacedAnimation ) )
			{
				//call the c4 Placement animation 
				m_bBombPlacedAnimation = true;

				SendWeaponAnim( ACT_VM_SECONDARYATTACK );
				
#if !defined( CLIENT_DLL )
				// player "place" animation
				//pPlayer->SetAnimation( PLAYER_HOLDBOMB );
#endif
			}
		}
	}

	if ( PlaceBomb && m_bStartedArming )
	{
		m_bStartedArming = false;
		m_fArmedTime = 0;
		
		if( pPlayer->m_bInBombZone )
		{
#if !defined( CLIENT_DLL )

			CPlantedC4 *pC4 = CPlantedC4::ShootSatchelCharge( pPlayer, pPlayer->GetAbsOrigin(), pPlayer->GetAbsAngles() );

			if ( pC4 )
			{
				pC4->SetBombSiteIndex( pPlayer->m_iBombSiteIndex );

				trace_t tr;
				UTIL_TraceEntity( pC4, GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-200), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
				pC4->SetAbsOrigin( tr.endpos );

				CBombTarget *pBombTarget = (CBombTarget*)UTIL_EntityByIndex( pPlayer->m_iBombSiteIndex );
				
				if ( pBombTarget )
				{
					CBaseEntity *pAttachPoint = gEntList.FindEntityByName( NULL, pBombTarget->GetBombMountTarget() );

					if ( pAttachPoint )
					{
						pC4->SetAbsOrigin( pAttachPoint->GetAbsOrigin() );
						pC4->SetAbsAngles( pAttachPoint->GetAbsAngles() );
						pC4->SetParent( pAttachPoint );
					}

					variant_t emptyVariant;
					pBombTarget->AcceptInput( "BombPlanted", pC4, pC4, emptyVariant, 0 );
				}
			}

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_planted" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt("posx", pPlayer->GetAbsOrigin().x );
				event->SetInt("posy", pPlayer->GetAbsOrigin().y );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}

			// Fire a beep event also so the bots have a chance to hear the bomb
			event = gameeventmanager->CreateEvent( "bomb_beep" );

			if ( event )
			{
				event->SetInt( "entindex", entindex() );
				gameeventmanager->FireEvent( event );
			}

			pPlayer->SetProgressBarTime( 0 );

			CSGameRules()->m_bBombDropped = false;
			CSGameRules()->m_bBombPlanted = true;

			// Play the plant sound.
			Vector plantPosition = pPlayer->GetAbsOrigin() + Vector( 0, 0, 5 );
			CPASAttenuationFilter filter( plantPosition );
			EmitSound( filter, entindex(), "c4.plant" );

			// release the player from being frozen
			pPlayer->ResetMaxSpeed();

			// No more c4!
			pPlayer->Weapon_Drop( this, NULL, NULL );
			UTIL_Remove( this );
#endif
			//don't allow the planting to start over again next frame.
			m_bBombPlanted = true;

			return;
		}
		else
		{
			ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Activated_At_Bomb_Spot" );

#if !defined( CLIENT_DLL )
			//pPlayer->SetAnimation( PLAYER_HOLDBOMB );

			// release the player from being frozen
			pPlayer->ResetMaxSpeed();

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}
#endif

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
			return;
		}
	}

	m_flNextPrimaryAttack = gpGlobals->curtime + 0.3;
	SetWeaponIdleTime( gpGlobals->curtime + SharedRandomFloat("C4IdleTime", 10, 15 ) );
}
Beispiel #27
0
CBaseEntity *CBasePlayer::FindUseEntity()
{
	Vector forward, up;
	EyeVectors( &forward, NULL, &up );

	trace_t tr;
	// Search for objects in a sphere (tests for entities that are not solid, yet still useable)
	Vector searchCenter = EyePosition();

	// NOTE: Some debris objects are useable too, so hit those as well
	// A button, etc. can be made out of clip brushes, make sure it's +useable via a traceline, too.
	int useableContents = MASK_SOLID | CONTENTS_DEBRIS | CONTENTS_PLAYERCLIP;

#ifdef CSTRIKE_DLL
	useableContents = MASK_NPCSOLID_BRUSHONLY | MASK_OPAQUE_AND_NPCS;
#endif

#ifdef HL1_DLL
	useableContents = MASK_SOLID;
#endif
#ifndef CLIENT_DLL
	CBaseEntity *pFoundByTrace = NULL;
#endif

	// UNDONE: Might be faster to just fold this range into the sphere query
	CBaseEntity *pObject = NULL;

	float nearestDist = FLT_MAX;
	// try the hit entity if there is one, or the ground entity if there isn't.
	CBaseEntity *pNearest = NULL;

	const int NUM_TANGENTS = 8;
	// trace a box at successive angles down
	//							forward, 45 deg, 30 deg, 20 deg, 15 deg, 10 deg, -10, -15
	const float tangents[NUM_TANGENTS] = { 0, 1, 0.57735026919f, 0.3639702342f, 0.267949192431f, 0.1763269807f, -0.1763269807f, -0.267949192431f };
	for ( int i = 0; i < NUM_TANGENTS; i++ )
	{
		if ( i == 0 )
		{
			UTIL_TraceLine( searchCenter, searchCenter + forward * 1024, useableContents, this, COLLISION_GROUP_NONE, &tr );
		}
		else
		{
			Vector down = forward - tangents[i]*up;
			VectorNormalize(down);
			UTIL_TraceHull( searchCenter, searchCenter + down * 72, -Vector(16,16,16), Vector(16,16,16), useableContents, this, COLLISION_GROUP_NONE, &tr );
		}
		pObject = tr.m_pEnt;

#ifndef CLIENT_DLL
		pFoundByTrace = pObject;
#endif
		bool bUsable = IsUseableEntity(pObject, 0);
		while ( pObject && !bUsable && pObject->GetMoveParent() )
		{
			pObject = pObject->GetMoveParent();
			bUsable = IsUseableEntity(pObject, 0);
		}

		if ( bUsable )
		{
			Vector delta = tr.endpos - tr.startpos;
			float centerZ = CollisionProp()->WorldSpaceCenter().z;
			delta.z = IntervalDistance( tr.endpos.z, centerZ + CollisionProp()->OBBMins().z, centerZ + CollisionProp()->OBBMaxs().z );
			float dist = delta.Length();
			if ( dist < PLAYER_USE_RADIUS )
			{
#ifndef CLIENT_DLL

				if ( sv_debug_player_use.GetBool() )
				{
					NDebugOverlay::Line( searchCenter, tr.endpos, 0, 255, 0, true, 30 );
					NDebugOverlay::Cross3D( tr.endpos, 16, 0, 255, 0, true, 30 );
				}

				if ( pObject->MyNPCPointer() && pObject->MyNPCPointer()->IsPlayerAlly( this ) )
				{
					// If about to select an NPC, do a more thorough check to ensure
					// that we're selecting the right one from a group.
					pObject = DoubleCheckUseNPC( pObject, searchCenter, forward );
				}
#endif
				if ( sv_debug_player_use.GetBool() )
				{
					Msg( "Trace using: %s\n", pObject ? pObject->GetDebugName() : "no usable entity found" );
				}

				pNearest = pObject;
				
				// if this is directly under the cursor just return it now
				if ( i == 0 )
					return pObject;
			}
		}
	}

	// check ground entity first
	// if you've got a useable ground entity, then shrink the cone of this search to 45 degrees
	// otherwise, search out in a 90 degree cone (hemisphere)
	if ( GetGroundEntity() && IsUseableEntity(GetGroundEntity(), FCAP_USE_ONGROUND) )
	{
		pNearest = GetGroundEntity();
	}
	if ( pNearest )
	{
		// estimate nearest object by distance from the view vector
		Vector point;
		pNearest->CollisionProp()->CalcNearestPoint( searchCenter, &point );
		nearestDist = CalcDistanceToLine( point, searchCenter, forward );
		if ( sv_debug_player_use.GetBool() )
		{
			Msg("Trace found %s, dist %.2f\n", pNearest->GetClassname(), nearestDist );
		}
	}

	for ( CEntitySphereQuery sphere( searchCenter, PLAYER_USE_RADIUS ); ( pObject = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
	{
		if ( !pObject )
			continue;

		if ( !IsUseableEntity( pObject, FCAP_USE_IN_RADIUS ) )
			continue;

		// see if it's more roughly in front of the player than previous guess
		Vector point;
		pObject->CollisionProp()->CalcNearestPoint( searchCenter, &point );

		Vector dir = point - searchCenter;
		VectorNormalize(dir);
		float dot = DotProduct( dir, forward );

		// Need to be looking at the object more or less
		if ( dot < 0.8 )
			continue;

		float dist = CalcDistanceToLine( point, searchCenter, forward );

		if ( sv_debug_player_use.GetBool() )
		{
			Msg("Radius found %s, dist %.2f\n", pObject->GetClassname(), dist );
		}

		if ( dist < nearestDist )
		{
			// Since this has purely been a radius search to this point, we now
			// make sure the object isn't behind glass or a grate.
			trace_t trCheckOccluded;
			UTIL_TraceLine( searchCenter, point, useableContents, this, COLLISION_GROUP_NONE, &trCheckOccluded );

			if ( trCheckOccluded.fraction == 1.0 || trCheckOccluded.m_pEnt == pObject )
			{
				pNearest = pObject;
				nearestDist = dist;
			}
		}
	}

#ifndef CLIENT_DLL
	if ( !pNearest )
	{
		// Haven't found anything near the player to use, nor any NPC's at distance.
		// Check to see if the player is trying to select an NPC through a rail, fence, or other 'see-though' volume.
		trace_t trAllies;
		UTIL_TraceLine( searchCenter, searchCenter + forward * PLAYER_USE_RADIUS, MASK_OPAQUE_AND_NPCS, this, COLLISION_GROUP_NONE, &trAllies );

		if ( trAllies.m_pEnt && IsUseableEntity( trAllies.m_pEnt, 0 ) && trAllies.m_pEnt->MyNPCPointer() && trAllies.m_pEnt->MyNPCPointer()->IsPlayerAlly( this ) )
		{
			// This is an NPC, take it!
			pNearest = trAllies.m_pEnt;
		}
	}

	if ( pNearest && pNearest->MyNPCPointer() && pNearest->MyNPCPointer()->IsPlayerAlly( this ) )
	{
		pNearest = DoubleCheckUseNPC( pNearest, searchCenter, forward );
	}

	if ( sv_debug_player_use.GetBool() )
	{
		if ( !pNearest )
		{
			NDebugOverlay::Line( searchCenter, tr.endpos, 255, 0, 0, true, 30 );
			NDebugOverlay::Cross3D( tr.endpos, 16, 255, 0, 0, true, 30 );
		}
		else if ( pNearest == pFoundByTrace )
		{
			NDebugOverlay::Line( searchCenter, tr.endpos, 0, 255, 0, true, 30 );
			NDebugOverlay::Cross3D( tr.endpos, 16, 0, 255, 0, true, 30 );
		}
		else
		{
			NDebugOverlay::Box( pNearest->WorldSpaceCenter(), Vector(-8, -8, -8), Vector(8, 8, 8), 0, 255, 0, true, 30 );
		}
	}
#endif

	if ( sv_debug_player_use.GetBool() )
	{
		Msg( "Radial using: %s\n", pNearest ? pNearest->GetDebugName() : "no usable entity found" );
	}

	return pNearest;
}
Beispiel #28
0
void CGameRules::RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore )
{
	const int MASK_RADIUS_DAMAGE = MASK_SHOT&(~CONTENTS_HITBOX);
	CBaseEntity *pEntity = NULL;
	trace_t		tr;
	float		flAdjustedDamage, falloff;
	Vector		vecSpot;

	Vector vecSrc = vecSrcIn;

	if ( flRadius )
		falloff = info.GetDamage() / flRadius;
	else
		falloff = 1.0;

	int bInWater = (UTIL_PointContents ( vecSrc ) & MASK_WATER) ? true : false;

#ifdef HL2_DLL
	if( bInWater )
	{
		// Only muffle the explosion if deeper than 2 feet in water.
		if( !(UTIL_PointContents(vecSrc + Vector(0, 0, 24)) & MASK_WATER) )
		{
			bInWater = false;
		}
	}
#endif // HL2_DLL
	
	vecSrc.z += 1;// in case grenade is lying on the ground

	float flHalfRadiusSqr = Square( flRadius / 2.0f );

	// iterate on all entities in the vicinity.
	for ( CEntitySphereQuery sphere( vecSrc, flRadius ); (pEntity = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() )
	{
		// This value is used to scale damage when the explosion is blocked by some other object.
		float flBlockedDamagePercent = 0.0f;

		if ( pEntity == pEntityIgnore )
			continue;

		if ( pEntity->m_takedamage == DAMAGE_NO )
			continue;

		// UNDONE: this should check a damage mask, not an ignore
		if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore )
		{// houndeyes don't hurt other houndeyes with their attack
			continue;
		}

		// blast's don't tavel into or out of water
		if (bInWater && pEntity->GetWaterLevel() == 0)
			continue;

		if (!bInWater && pEntity->GetWaterLevel() == 3)
			continue;

		// Check that the explosion can 'see' this entity.
		vecSpot = pEntity->BodyTarget( vecSrc, false );
		UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );

		if( old_radius_damage.GetBool() )
		{
			if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
			continue;
		}
		else
		{
			if ( tr.fraction != 1.0 )
			{
				if ( IsExplosionTraceBlocked(&tr) )
				{
					if( ShouldUseRobustRadiusDamage( pEntity ) )
					{
						if( vecSpot.DistToSqr( vecSrc ) > flHalfRadiusSqr )
						{
							// Only use robust model on a target within one-half of the explosion's radius.
							continue;
						}

						Vector vecToTarget = vecSpot - tr.endpos;
						VectorNormalize( vecToTarget );

						// We're going to deflect the blast along the surface that 
						// interrupted a trace from explosion to this target.
						Vector vecUp, vecDeflect;
						CrossProduct( vecToTarget, tr.plane.normal, vecUp );
						CrossProduct( tr.plane.normal, vecUp, vecDeflect );
						VectorNormalize( vecDeflect );

						// Trace along the surface that intercepted the blast...
						UTIL_TraceLine( tr.endpos, tr.endpos + vecDeflect * ROBUST_RADIUS_PROBE_DIST, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
						//NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 255, 0, false, 10 );

						// ...to see if there's a nearby edge that the explosion would 'spill over' if the blast were fully simulated.
						UTIL_TraceLine( tr.endpos, vecSpot, MASK_RADIUS_DAMAGE, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );
						//NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, false, 10 );

						if( tr.fraction != 1.0 && tr.DidHitWorld() )
						{
							// Still can't reach the target.
							continue;
						}
						// else fall through
					}
					else
					{
						continue;
					}
				}

				// UNDONE: Probably shouldn't let children block parents either?  Or maybe those guys should set their owner if they want this behavior?
				// HL2 - Dissolve damage is not reduced by interposing non-world objects
				if( tr.m_pEnt && tr.m_pEnt != pEntity && tr.m_pEnt->GetOwnerEntity() != pEntity )
				{
					// Some entity was hit by the trace, meaning the explosion does not have clear
					// line of sight to the entity that it's trying to hurt. If the world is also
					// blocking, we do no damage.
					CBaseEntity *pBlockingEntity = tr.m_pEnt;
					//Msg( "%s may be blocked by %s...", pEntity->GetClassname(), pBlockingEntity->GetClassname() );

					UTIL_TraceLine( vecSrc, vecSpot, CONTENTS_SOLID, info.GetInflictor(), COLLISION_GROUP_NONE, &tr );

					if( tr.fraction != 1.0 )
					{
						continue;
					}
					
					// Now, if the interposing object is physics, block some explosion force based on its mass.
					if( pBlockingEntity->VPhysicsGetObject() )
					{
						const float MASS_ABSORB_ALL_DAMAGE = 350.0f;
						float flMass = pBlockingEntity->VPhysicsGetObject()->GetMass();
						float scale = flMass / MASS_ABSORB_ALL_DAMAGE;

						// Absorbed all the damage.
						if( scale >= 1.0f )
						{
							continue;
						}

						ASSERT( scale > 0.0f );
						flBlockedDamagePercent = scale;
						//Msg("  Object (%s) weighing %fkg blocked %f percent of explosion damage\n", pBlockingEntity->GetClassname(), flMass, scale * 100.0f);
					}
					else
					{
						// Some object that's not the world and not physics. Generically block 25% damage
						flBlockedDamagePercent = 0.25f;
					}
				}
			}
		}
		// decrease damage for an ent that's farther from the bomb.
		flAdjustedDamage = ( vecSrc - tr.endpos ).Length() * falloff;
		flAdjustedDamage = info.GetDamage() - flAdjustedDamage;

		if ( flAdjustedDamage <= 0 )
		{
			continue;
		}

		// the explosion can 'see' this entity, so hurt them!
		if (tr.startsolid)
		{
			// if we're stuck inside them, fixup the position and distance
			tr.endpos = vecSrc;
			tr.fraction = 0.0;
		}
		
		CTakeDamageInfo adjustedInfo = info;
		//Msg("%s: Blocked damage: %f percent (in:%f  out:%f)\n", pEntity->GetClassname(), flBlockedDamagePercent * 100, flAdjustedDamage, flAdjustedDamage - (flAdjustedDamage * flBlockedDamagePercent) );
		adjustedInfo.SetDamage( flAdjustedDamage - (flAdjustedDamage * flBlockedDamagePercent) );

		// Now make a consideration for skill level!
		if( info.GetAttacker() && info.GetAttacker()->IsPlayer() && pEntity->IsNPC() )
		{
			// An explosion set off by the player is harming an NPC. Adjust damage accordingly.
			adjustedInfo.AdjustPlayerDamageInflictedForSkillLevel();
		}

		Vector dir = vecSpot - vecSrc;
		VectorNormalize( dir );

		// If we don't have a damage force, manufacture one
		if ( adjustedInfo.GetDamagePosition() == vec3_origin || adjustedInfo.GetDamageForce() == vec3_origin )
		{
			if ( !( adjustedInfo.GetDamageType() & DMG_PREVENT_PHYSICS_FORCE ) )
			{
				CalculateExplosiveDamageForce( &adjustedInfo, dir, vecSrc );
			}
		}
		else
		{
			// Assume the force passed in is the maximum force. Decay it based on falloff.
			float flForce = adjustedInfo.GetDamageForce().Length() * falloff;
			adjustedInfo.SetDamageForce( dir * flForce );
			adjustedInfo.SetDamagePosition( vecSrc );
		}

		if ( tr.fraction != 1.0 && pEntity == tr.m_pEnt )
		{
			ClearMultiDamage( );
			pEntity->DispatchTraceAttack( adjustedInfo, dir, &tr );
			ApplyMultiDamage();
		}
		else
		{
			pEntity->TakeDamage( adjustedInfo );
		}

		// Now hit all triggers along the way that respond to damage... 
		pEntity->TraceAttackToTriggers( adjustedInfo, vecSrc, tr.endpos, dir );

#if defined( GAME_DLL )
		if ( info.GetAttacker() && info.GetAttacker()->IsPlayer() && ToBaseCombatCharacter( tr.m_pEnt ) )
		{

			// This is a total hack!!!
			bool bIsPrimary = true;
			CBasePlayer *player = ToBasePlayer( info.GetAttacker() );
			CBaseCombatWeapon *pWeapon = player->GetActiveWeapon();
			if ( pWeapon && FClassnameIs( pWeapon, "weapon_smg1" ) )
			{
				bIsPrimary = false;
			}

			gamestats->Event_WeaponHit( player, bIsPrimary, (pWeapon != NULL) ? player->GetActiveWeapon()->GetClassname() : "NULL", info );
		}
#endif
	}
}
Beispiel #29
0
void CNihilanthHVR :: ZapThink( void  )
{
	pev->nextthink = gpGlobals->time + 0.05;

	// check world boundaries
	if (m_hEnemy == NULL ||  pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096)
	{
		SetTouch( NULL );
		UTIL_Remove( this );
		return;
	}

	if (pev->velocity.Length() < 2000)
	{
		pev->velocity = pev->velocity * 1.2;
	}


	// MovetoTarget( m_hEnemy->Center( ) );

	if ((m_hEnemy->Center() - pev->origin).Length() < 256)
	{
		TraceResult tr;

		UTIL_TraceLine( pev->origin, m_hEnemy->Center(), dont_ignore_monsters, edict(), &tr );

		CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit);
		if (pEntity != NULL && pEntity->pev->takedamage)
		{
			ClearMultiDamage( );
			pEntity->TraceAttack( pev, gSkillData.nihilanthZap, pev->velocity, &tr, DMG_SHOCK );
			ApplyMultiDamage( pev, pev );
		}

		MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
			WRITE_BYTE( TE_BEAMENTPOINT );
			WRITE_SHORT( entindex() );
			WRITE_COORD( tr.vecEndPos.x );
			WRITE_COORD( tr.vecEndPos.y );
			WRITE_COORD( tr.vecEndPos.z );
			WRITE_SHORT( g_sModelIndexLaser );
			WRITE_BYTE( 0 ); // frame start
			WRITE_BYTE( 10 ); // framerate
			WRITE_BYTE( 3 ); // life
			WRITE_BYTE( 20 );  // width
			WRITE_BYTE( 20 );   // noise
			WRITE_BYTE( 64 );   // r, g, b
			WRITE_BYTE( 196 );   // r, g, b
			WRITE_BYTE( 255);   // r, g, b
			WRITE_BYTE( 255 );	// brightness
			WRITE_BYTE( 10 );		// speed
		MESSAGE_END();

		UTIL_EmitAmbientSound( edict(), tr.vecEndPos, "weapons/electro4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) );

		SetTouch( NULL );
		UTIL_Remove( this );
		pev->nextthink = gpGlobals->time + 0.2;
		return;
	}

	pev->frame = (int)(pev->frame + 1) % 11;

	MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
		WRITE_BYTE( TE_ELIGHT );
		WRITE_SHORT( entindex( ) );		// entity, attachment
		WRITE_COORD( pev->origin.x );		// origin
		WRITE_COORD( pev->origin.y );
		WRITE_COORD( pev->origin.z );
		WRITE_COORD( 128 );	// radius
		WRITE_BYTE( 128 );	// R
		WRITE_BYTE( 128 );	// G
		WRITE_BYTE( 255 );	// B
		WRITE_BYTE( 10 );	// life * 10
		WRITE_COORD( 128 ); // decay
	MESSAGE_END();

	// Crawl( );
}
Beispiel #30
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CFastZombie::StartTask( const Task_t *pTask )
{
    switch( pTask->iTask )
    {
    case TASK_FASTZOMBIE_VERIFY_ATTACK:
        // Simply ensure that the zombie still has a valid melee attack
        if( HasCondition( COND_CAN_MELEE_ATTACK1 ) )
        {
            TaskComplete();
        }
        else
        {
            TaskFail("");
        }
        break;

    case TASK_FASTZOMBIE_JUMP_BACK:
    {
        SetActivity( ACT_IDLE );

        RemoveFlag( FL_ONGROUND );

        BeginAttackJump();

        Vector forward;
        AngleVectors( GetLocalAngles(), &forward );

        //
        // Take him off ground so engine doesn't instantly reset FL_ONGROUND.
        //
        UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 ));

        ApplyAbsVelocityImpulse( forward * -200 + Vector( 0, 0, 200 ) );
    }
    break;

    case TASK_FASTZOMBIE_UNSTICK_JUMP:
    {
        RemoveFlag( FL_ONGROUND );

        // Call begin attack jump. A little bit later if we fail to pathfind, we check
        // this value to see if we just jumped. If so, we assume we've jumped
        // to someplace that's not pathing friendly, and so must jump again to get out.
        BeginAttackJump();

        //
        // Take him off ground so engine doesn't instantly reset FL_ONGROUND.
        //
        UTIL_SetOrigin( this, GetLocalOrigin() + Vector( 0 , 0 , 1 ));

        CBaseEntity *pEnemy = GetEnemy();
        Vector vecJumpDir;

        if ( GetActivity() == ACT_CLIMB_UP || GetActivity() == ACT_CLIMB_DOWN )
        {
            // Jump off the pipe backwards!
            Vector forward;

            GetVectors( &forward, NULL, NULL );

            ApplyAbsVelocityImpulse( forward * -200 );
        }
        else if( pEnemy )
        {
            vecJumpDir = pEnemy->GetLocalOrigin() - GetLocalOrigin();
            VectorNormalize( vecJumpDir );
            vecJumpDir.z = 0;

            ApplyAbsVelocityImpulse( vecJumpDir * 300 + Vector( 0, 0, 200 ) );
        }
        else
        {
            Msg("UNHANDLED CASE! Stuck Fast Zombie with no enemy!\n");
        }
    }
    break;

    case TASK_WAIT_FOR_MOVEMENT:
        // If we're waiting for movement, that means that pathfinding succeeded, and
        // we're about to be moving. So we aren't stuck. So clear this flag.
        m_fJustJumped = false;

        BaseClass::StartTask( pTask );
        break;

    case TASK_FACE_ENEMY:
    {
        // We don't use the base class implementation of this, because GetTurnActivity
        // stomps our landing scrabble animations (sjb)
        Vector flEnemyLKP = GetEnemyLKP();
        GetMotor()->SetIdealYawToTarget( flEnemyLKP );
    }
    break;

    case TASK_FASTZOMBIE_LAND_RECOVER:
    {
        // Set the ideal yaw
        Vector flEnemyLKP = GetEnemyLKP();
        GetMotor()->SetIdealYawToTarget( flEnemyLKP );

        // figure out which way to turn.
        float flDeltaYaw = GetMotor()->DeltaIdealYaw();

        if( flDeltaYaw < 0 )
        {
            SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_RIGHT );
        }
        else
        {
            SetIdealActivity( (Activity)ACT_FASTZOMBIE_LAND_LEFT );
        }


        TaskComplete();
    }
    break;

    case TASK_RANGE_ATTACK1:

        // Make melee attacks impossible until we land!
        m_flNextMeleeAttack = gpGlobals->curtime + 60;

        SetTouch( LeapAttackTouch );
        break;

    case TASK_FASTZOMBIE_DO_ATTACK:
        SetActivity( (Activity)ACT_FASTZOMBIE_LEAP_SOAR );
        break;

    default:
        BaseClass::StartTask( pTask );
        break;
    }
}