void CEnvHeadcrabCanister::TestForCollisionsAgainstWorld( const Vector &vecEndPosition )
{
	// Splash damage!
	// Iterate on all entities in the vicinity.
	float flDamageRadius = m_flDamageRadius;
	float flDamage = m_flDamage;

	CEntity *pEntity;
	for ( CEntitySphereQuery sphere( vecEndPosition, flDamageRadius ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
	{
		if ( pEntity == this )
			continue;

		if ( !pEntity->IsSolid() )
			continue;

		// Get distance to object and use it as a scale value.
		Vector vecSegment;
		VectorSubtract( pEntity->GetAbsOrigin(), vecEndPosition, vecSegment ); 
		float flDistance = VectorNormalize( vecSegment );

		float flFactor = 1.0f / ( flDamageRadius * (INNER_RADIUS_FRACTION - 1) );
		flFactor *= flFactor;
		float flScale = flDistance - flDamageRadius;
		flScale *= flScale * flFactor;
		if ( flScale > 1.0f ) 
		{ 
			flScale = 1.0f; 
		}
		
		// Check for a physics object and apply force!
		Vector vecForceDir = vecSegment;
		IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
		if ( pPhysObject )
		{
			// Send it flying!!!
			float flMass = PhysGetEntityMass( pEntity );
			vecForceDir *= flMass * 750 * flScale;
			pPhysObject->ApplyForceCenter( vecForceDir );
		}

		if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) )
		{
			CTakeDamageInfo info( BaseEntity(), BaseEntity(), flDamage * flScale, DMG_BLAST );
			CalculateExplosiveDamageForce( &info, vecSegment, pEntity->GetAbsOrigin() );
			pEntity->TakeDamage( info );
		}

		if ( pEntity->IsPlayer() && !(static_cast<CPlayer*>(pEntity)->IsInAVehicle()) )
		{
			if (vecSegment.z < 0.1f)
			{
				vecSegment.z = 0.1f;
				VectorNormalize( vecSegment );					
			}
			float flAmount = SimpleSplineRemapVal( flScale, 0.0f, 1.0f, 250.0f, 1000.0f );
			pEntity->ApplyAbsVelocityImpulse( vecSegment * flAmount );
		}
	}
}
//-----------------------------------------------------------------------------
// Landed!
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::Landed( void )
{
	EmitSound( "HeadcrabCanister.AfterLanding" );

	// Lock us now that we've stopped
	SetLanded();

	// Hook the follow trail to the lead of the canister (which should be buried)
	// to hide problems with the edge of the follow trail
	if (m_hTrail)
	{
		m_hTrail->SetAttachment( BaseEntity(), LookupAttachment("trail") );
	}

	// Start smoke, unless we don't want it
	if ( !HasSpawnFlags( SF_NO_SMOKE ) )
	{
		// Create the smoke trail to obscure the headcrabs
		CSmokeTrail *trail = CSmokeTrail::CreateSmokeTrail();
		trail->FollowEntity( BaseEntity(), "smoke" );

		trail->m_SpawnRate			= 8;
		trail->m_ParticleLifetime	= 2.0f;

		trail->m_StartColor->Init( 0.7f, 0.7f, 0.7f );
		trail->m_EndColor->Init( 0.6, 0.6, 0.6 );

		trail->m_StartSize	= 32;
		trail->m_EndSize	= 64;
		trail->m_SpawnRadius= 8;
		trail->m_MinSpeed	= 0;
		trail->m_MaxSpeed	= 8;
		trail->m_MinDirectedSpeed	= 32;
		trail->m_MaxDirectedSpeed	= 64;
		trail->m_Opacity	= 0.35f;

		trail->SetLifetime( m_flSmokeLifetime );

		m_hSmokeTrail.Set(trail->BaseEntity());
	}

	SetThink( NULL );

	if ( !HasSpawnFlags( SF_WAIT_FOR_INPUT_TO_OPEN ) )
	{
		if ( HasSpawnFlags( SF_START_IMPACTED ) )
		{
			CanisterFinishedOpening( );
		}
		else
		{
			OpenCanister();
		}
	}
}
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
Vector CAI_BasePhysicsFlyingBot::VelocityToAvoidObstacles(float flInterval)
{
	// --------------------------------
	//  Avoid banging into stuff
	// --------------------------------
	trace_t tr;
	Vector vTravelDir = m_vCurrentVelocity*flInterval;
	Vector endPos = GetAbsOrigin() + vTravelDir;
	UTIL_TraceEntity( this, GetAbsOrigin(), endPos, MASK_NPCSOLID|CONTENTS_WATER, &tr);
	if (tr.fraction != 1.0)
	{	
		// Bounce off in normal 
		Vector vBounce = tr.plane.normal * 0.5 * m_vCurrentVelocity.Length();
		return (vBounce);
	}
	
	// --------------------------------
	// Try to remain above the ground.
	// --------------------------------
	float flMinGroundDist = MinGroundDist();
	UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() + Vector(0, 0, -flMinGroundDist), 
		MASK_NPCSOLID_BRUSHONLY|CONTENTS_WATER, BaseEntity(), COLLISION_GROUP_NONE, &tr);
	if (tr.fraction < 1)
	{
		// Clamp veloctiy
		if (tr.fraction < 0.1)
		{
			tr.fraction = 0.1;
		}

		return Vector(0, 0, 50/tr.fraction);
	}
	return vec3_origin;
}
void CE_Cycler_Fix::Think(void)
{
	VALVE_BASEPTR original_think = m_pfnThink;
	if(original_think != NULL)
	{
		(BaseEntity()->*original_think)();
		return;
	}
}
//-----------------------------------------------------------------------------
// Fires the canister!
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::InputFireCanister( inputdata_t &inputdata )
{
	if (m_bLaunched)
		return;

	m_bLaunched = true;

	if ( HasSpawnFlags( SF_START_IMPACTED ) )
	{
		StartSpawningHeadcrabs( 0.01f );
		return;
	}

	// Play a firing sound
	CPASAttenuationFilter filter( this, ATTN_NONE );

	if ( !HasSpawnFlags( SF_NO_LAUNCH_SOUND ) )
	{
		EmitSound( filter, entindex(), "HeadcrabCanister.LaunchSound" );
	}

	// Place the canister
	CE_CSkyCamera *pCamera = PlaceCanisterInWorld();

	// Hook up a smoke trail
	CE_CSpriteTrail *trail = CE_CSpriteTrail::SpriteTrailCreate( "sprites/smoke.vmt", GetAbsOrigin(), true );
	trail->SetTransparency( kRenderTransAdd, 224, 224, 255, 255, kRenderFxNone );
	trail->SetAttachment( BaseEntity(), 0 );
	trail->SetStartWidth( 32.0 );
	trail->SetEndWidth( 200.0 );
	trail->SetStartWidthVariance( 15.0f );
	trail->SetTextureResolution( 0.002 );
	trail->SetLifeTime( ENV_HEADCRABCANISTER_TRAIL_TIME );
	trail->SetMinFadeLength( 1000.0f );
	m_hTrail.Set(trail->BaseEntity());

	if ( pCamera && m_Shared.IsInSkybox() )
	{
		m_hTrail->SetSkybox( pCamera->m_skyboxData->origin, pCamera->m_skyboxData->scale );
	}

	// Fire that output!
	m_OnLaunched.Set( BaseEntity(), BaseEntity(), BaseEntity() );
}
//-----------------------------------------------------------------------------
// Set up the world model
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::SetupWorldModel()
{
	SetModel( ENV_HEADCRABCANISTER_MODEL );
	SetSolid( SOLID_BBOX );

	float flRadius = CollisionProp()->BoundingRadius();
	Vector vecMins( -flRadius, -flRadius, -flRadius );
	Vector vecMaxs( flRadius, flRadius, flRadius );
	UTIL_SetSize( BaseEntity(), vecMins, vecMaxs );

}
//-----------------------------------------------------------------------------
// Test for impact!
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::TestForCollisionsAgainstEntities( const Vector &vecEndPosition )
{
	// Debugging!!
//	NDebugOverlay::Box( GetAbsOrigin(), m_vecMin * 0.5f, m_vecMax * 0.5f, 255, 255, 0, 0, 5 );
//	NDebugOverlay::Box( vecEndPosition, m_vecMin, m_vecMax, 255, 0, 0, 0, 5 );

	float flRadius = CollisionProp()->BoundingRadius();
	Vector vecMins( -flRadius, -flRadius, -flRadius );
	Vector vecMaxs( flRadius, flRadius, flRadius );

	Ray_t ray;
	ray.Init( GetAbsOrigin(), vecEndPosition, vecMins, vecMaxs );

	CCollideList collideList( &ray, BaseEntity(), MASK_SOLID );
	enginetrace->EnumerateEntities( ray, false, &collideList );

	float flDamage = m_flDamage;

	// Now get each entity and react accordinly!
	for( int iEntity = collideList.m_Entities.Count(); --iEntity >= 0; )
	{
		CEntity *pEntity = collideList.m_Entities[iEntity];
		Vector vecForceDir = m_Shared.m_vecDirection;

		// Check for a physics object and apply force!
		IPhysicsObject *pPhysObject = pEntity->VPhysicsGetObject();
		if ( pPhysObject )
		{
			float flMass = PhysGetEntityMass( pEntity );
			vecForceDir *= flMass * 750;
			pPhysObject->ApplyForceCenter( vecForceDir );
		}

		if ( pEntity->m_takedamage && ( m_flDamage != 0.0f ) )
		{
			CTakeDamageInfo info( BaseEntity(), BaseEntity(), flDamage, DMG_BLAST );
			CalculateExplosiveDamageForce( &info, vecForceDir, pEntity->GetAbsOrigin() );
			pEntity->TakeDamage( info );
		}
	}
}
//-----------------------------------------------------------------------------
// Spawn!
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::Spawn( void )
{
	Precache();
	BaseClass::Spawn();

	// Do we have a position to launch from?
	if ( m_iszLaunchPositionName != NULL_STRING )
	{
		// It doesn't have any real presence at first.
		SetSolid( SOLID_NONE );

		m_vecImpactPosition = GetAbsOrigin();
		m_bIncomingSoundStarted = false;
		m_bLanded = false;
		m_bHasDetonated = false;
		m_bOpened = false;
	}
	else if ( !HasSpawnFlags( SF_START_IMPACTED ) )
	{
		// It doesn't have any real presence at first.
		SetSolid( SOLID_NONE );

		if ( !HasSpawnFlags( SF_LAND_AT_INITIAL_POSITION ) )
		{
			Vector vecForward;
			GetVectors( &vecForward, NULL, NULL );
			vecForward *= -1.0f;

			trace_t trace;
			UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vecForward * 10000, MASK_NPCWORLDSTATIC, 
				BaseEntity(), COLLISION_GROUP_NONE, &trace );

			m_vecImpactPosition = trace.endpos;
		}
		else
		{
			m_vecImpactPosition = GetAbsOrigin();
		}

		m_bIncomingSoundStarted = false;
		m_bLanded = false;
		m_bHasDetonated = false;
		m_bOpened = false;
	}
	else
	{
		m_bHasDetonated = true;
		m_bIncomingSoundStarted = true;
		m_bOpened = false;
		m_vecImpactPosition = GetAbsOrigin();
		Landed();
	}
}
//-----------------------------------------------------------------------------
// Headcrab creation
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::HeadcrabCanisterSpawnHeadcrabThink()
{
	Vector vecSpawnPosition;
	QAngle vecSpawnAngles;

	--m_nHeadcrabCount;

	int nHeadCrabAttachment = LookupAttachment( "headcrab" );
	if ( GetAttachment( nHeadCrabAttachment, vecSpawnPosition, vecSpawnAngles ) )
	{
		CEntity *pEnt = CreateEntityByName( s_pHeadcrabClass[m_nHeadcrabType] );
		CBaseHeadcrab *pHeadCrab = assert_cast<CBaseHeadcrab*>(pEnt);

		// Necessary to get it to eject properly (don't allow the NPC
		// to override the spawn position specified).
		pHeadCrab->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );

		// So we don't collide with the canister
		// NOTE: Hierarchical attachment is necessary here to get the animations to work
		pHeadCrab->SetOwnerEntity( BaseEntity() );
		DispatchSpawn( pHeadCrab->BaseEntity() );
		pHeadCrab->SetParent( BaseEntity(), nHeadCrabAttachment );
		pHeadCrab->SetLocalOrigin( vec3_origin );
		pHeadCrab->SetLocalAngles( vec3_angle );
		pHeadCrab->CrawlFromCanister();
	}

	if ( m_nHeadcrabCount != 0 )
	{
		float flWaitTime = enginerandom->RandomFloat( 1.0f, 2.0f );
		SetContextThink( &CEnvHeadcrabCanister::HeadcrabCanisterSpawnHeadcrabThink_CBE, gpGlobals->curtime + flWaitTime, s_pHeadcrabThinkContext );
	}
	else
	{
		SetContextThink( NULL, gpGlobals->curtime, s_pHeadcrabThinkContext );
	}
}
void CE_CBeam::BeamDamage( trace_t *ptr )
{
	RelinkBeam();
	if ( ptr->fraction != 1.0 && ptr->m_pEnt != NULL )
	{
		CEntity *pHit = CEntity::Instance(ptr->m_pEnt);
		if ( pHit )
		{
			ClearMultiDamage();
			Vector dir = ptr->endpos - GetAbsOrigin();
			VectorNormalize( dir );
			int nDamageType = DMG_ENERGYBEAM;

			if (m_nDissolveType == 0)
			{
				nDamageType = DMG_DISSOLVE;
			}
			else if ( m_nDissolveType > 0 )
			{
				nDamageType = DMG_DISSOLVE | DMG_SHOCK; 
			}

			CTakeDamageInfo info( BaseEntity(), BaseEntity(), m_flDamage * (gpGlobals->curtime - m_flFireTime), nDamageType );
			CalculateMeleeDamageForce( &info, dir, ptr->endpos );
			pHit->DispatchTraceAttack( info, dir, ptr );
			ApplyMultiDamage();
			if ( HasSpawnFlags( SF_BEAM_DECALS ) )
			{
				if ( pHit->IsBSPModel() )
				{
					UTIL_DecalTrace( ptr, GetDecalName() );
				}
			}
		}
	}
	m_flFireTime = gpGlobals->curtime;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pActivator - 
//			*pCaller - 
//			useType - 
//			value - 
//-----------------------------------------------------------------------------
void CItem_AmmoCrate::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	CPlayer *pPlayer = ToBasePlayer( CEntity::Instance(pActivator) );

	if ( pPlayer == NULL )
		return;

	m_OnUsed.FireOutput( pActivator, this );

	int iSequence = LookupSequence( "Open" );

	// See if we're not opening already
	if ( GetSequence() != iSequence )
	{
		Vector mins, maxs;
		trace_t tr;

		CollisionProp()->WorldSpaceAABB( &mins, &maxs );

		Vector vOrigin = GetAbsOrigin();
		vOrigin.z += ( maxs.z - mins.z );
		mins = (mins - GetAbsOrigin()) * 0.2f;
		maxs = (maxs - GetAbsOrigin()) * 0.2f;
		mins.z = ( GetAbsOrigin().z - vOrigin.z );  
		
		UTIL_TraceHull( vOrigin, vOrigin, mins, maxs, MASK_SOLID, BaseEntity(), COLLISION_GROUP_NONE, &tr );

		if ( tr.startsolid || tr.allsolid )
			 return;
			
		m_hActivator.Set(pPlayer->BaseEntity());

		// Animate!
		ResetSequence( iSequence );

		// Make sound
		CPASAttenuationFilter sndFilter( this, "AmmoCrate.Open" );
		EmitSound( sndFilter, entindex(), "AmmoCrate.Open" );

		// Start thinking to make it return
		SetThink( &CItem_AmmoCrate::CrateThink );
		SetNextThink( gpGlobals->curtime + 0.1f );
	}

	// Don't close again for two seconds
	m_flCloseTime = gpGlobals->curtime + AMMO_CRATE_CLOSE_DELAY;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CItem_AmmoCrate::CrateThink( void )
{
	StudioFrameAdvance();
	DispatchAnimEvents( BaseEntity() );

	SetNextThink( gpGlobals->curtime + 0.1f );

	// Start closing if we're not already
	if ( GetSequence() != LookupSequence( "Close" ) )
	{
		// Not ready to close?
		if ( m_flCloseTime <= gpGlobals->curtime )
		{
			m_hActivator.Set(NULL);

			ResetSequence( LookupSequence( "Close" ) );
		}
	}
	else
	{
		// See if we're fully closed
		if ( IsSequenceFinished() )
		{
			// Stop thinking
			SetThink( NULL );
			CPASAttenuationFilter sndFilter( this, "AmmoCrate.Close" );
			EmitSound( sndFilter, entindex(), "AmmoCrate.Close" );

			// FIXME: We're resetting the sequence here
			// but setting Think to NULL will cause this to never have
			// StudioFrameAdvance called. What are the consequences of that?
			ResetSequence( LookupSequence( "Idle" ) );
			SetBodygroup( 1, true );
		}
	}
}
//-----------------------------------------------------------------------------
// Creates the explosion effect
//-----------------------------------------------------------------------------
void CEnvHeadcrabCanister::Detonate( )
{
	// Send the impact output
	m_OnImpacted.FireOutput( this, this, 0 );

	if ( !HasSpawnFlags( SF_NO_IMPACT_SOUND ) )
	{
		StopSound( "HeadcrabCanister.IncomingSound" );
		EmitSound( "HeadcrabCanister.Explosion" );
	}

	// If we're supposed to be removed, do that now
	if ( HasSpawnFlags( SF_REMOVE_ON_IMPACT ) )
	{
		SetAbsOrigin( m_vecImpactPosition );
		SetModel( ENV_HEADCRABCANISTER_BROKEN_MODEL );
		SetMoveType( MOVETYPE_NONE );
		AddEffects( EF_NOINTERP );
		m_bLanded = true;
		
		// Become invisible so our trail can finish up
		AddEffects( EF_NODRAW );
		SetSolidFlags( FSOLID_NOT_SOLID );

		SetThink( &CEnvHeadcrabCanister::SUB_Remove );
		SetNextThink( gpGlobals->curtime + ENV_HEADCRABCANISTER_TRAIL_TIME );

		return;
	}

	// Test for damaging things
	TestForCollisionsAgainstWorld( m_vecImpactPosition );

	// Shake the screen unless flagged otherwise
	if ( !HasSpawnFlags( SF_NO_SHAKE ) )
	{
		CPlayer *pPlayer = UTIL_PlayerByIndex( 1 );

		// If the player is on foot, then do a more limited shake
		float shakeRadius = ( pPlayer && pPlayer->IsInAVehicle() ) ? sk_env_headcrabcanister_shake_radius_vehicle.GetFloat() : sk_env_headcrabcanister_shake_radius.GetFloat();

		UTIL_ScreenShake( m_vecImpactPosition, sk_env_headcrabcanister_shake_amplitude.GetFloat(), 150.0, 1.0, shakeRadius, SHAKE_START );
	}

	// Do explosion effects
	if ( !HasSpawnFlags( SF_NO_IMPACT_EFFECTS ) )
	{
		// Normal explosion
		ExplosionCreate( m_vecImpactPosition, GetAbsAngles(), BaseEntity(), 50, 500, 
			SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSOUND, 1300.0f );
			
		// Dust explosion
		//CE_TODO
		/*AR2Explosion *pExplosion = AR2Explosion::CreateAR2Explosion( m_vecImpactPosition );
		
		if( pExplosion )
		{
			pExplosion->SetLifetime(10);
		}*/
	}
}
int CE_Cycler_Fix::OnTakeDamage_Alive(const CTakeDamageInfo& info)
{
#if 0
	return BaseClass::OnTakeDamage_Alive(info);
#endif

	Forget( bits_MEMORY_INCOVER );

	if ( !CCombatCharacter::FAKE_OnTakeDamage_Alive( info ) )
		return 0;

	if ( GetSleepState() == AISS_WAITING_FOR_THREAT )
		Wake();

	CEntity *attacker = CEntity::Instance(info.GetAttacker());

	// NOTE: This must happen after the base class is called; we need to reduce
	// health before the pain sound, since some NPCs use the final health
	// level as a modifier to determine which pain sound to use.

	// REVISIT: Combine soldiers shoot each other a lot and then talk about it
	// this improves that case a bunch, but it seems kind of harsh.
	if ( !GetSquad() || !GetSquad()->SquadIsMember( attacker ) )
	{
		PainSound( info );// "Ouch!"
	}

	// See if we're running a dynamic interaction that should break when I am damaged.
	if ( IsActiveDynamicInteraction() )
	{
		ScriptedNPCInteraction_t *pInteraction = GetRunningDynamicInteraction();
		if ( pInteraction->iLoopBreakTriggerMethod & SNPCINT_LOOPBREAK_ON_DAMAGE )
		{
			CEAI_ScriptedSequence *_m_hCine = Get_m_hCine();
			// Can only break when we're in the action anim
			if ( _m_hCine->IsPlayingAction() )
			{
				_m_hCine->StopActionLoop( true );
			}
		}
	}

	// If we're not allowed to die, refuse to die
	// Allow my interaction partner to kill me though

	if ( m_iHealth <= 0 && HasInteractionCantDie() && attacker != m_hInteractionPartner )
	{
		m_iHealth = 1;
	}

	// -----------------------------------
	//  Fire outputs
 	// -----------------------------------
	if ( m_flLastDamageTime != gpGlobals->curtime )
	{
		// only fire once per frame
		m_OnDamaged->FireOutput( attacker, this);

		if( attacker && attacker->IsPlayer() )
		{
			m_OnDamagedByPlayer->FireOutput( attacker, this );
			
			// This also counts as being harmed by player's squad.
			m_OnDamagedByPlayerSquad->FireOutput( attacker, this );
		} else {
			// See if the person that injured me is an NPC.
			CAI_NPC *pAttacker = dynamic_cast<CAI_NPC *>( attacker );

			if( pAttacker && pAttacker->IsAlive() )
			{
				if( pAttacker->GetSquad() != NULL && pAttacker->IsInPlayerSquad() )
				{
					m_OnDamagedByPlayerSquad->FireOutput( attacker, this );
				}
			}
		}
	}

	if( (info.GetDamageType() & DMG_CRUSH) && !(info.GetDamageType() & DMG_PHYSGUN) && info.GetDamage() >= MIN_PHYSICS_FLINCH_DAMAGE )
	{
		SetCondition( COND_PHYSICS_DAMAGE );
	}

	if ( m_iHealth <= ( m_iMaxHealth / 2 ) )
	{
		m_OnHalfHealth->FireOutput( attacker, this );
	}

	// react to the damage (get mad)
	if ( ( (GetFlags() & FL_NPC) == 0 ) || !attacker )
		return 1;

	// If the attacker was an NPC or client update my position memory
	if ( attacker->GetFlags() & (FL_NPC | FL_CLIENT) )
	{
		// ------------------------------------------------------------------
		//				DO NOT CHANGE THIS CODE W/O CONSULTING
		// Only update information about my attacker I don't see my attacker
		// ------------------------------------------------------------------
		if ( !FInViewCone_Entity( info.GetAttacker() ) || !FVisible_Entity( info.GetAttacker() ) )
		{
			// -------------------------------------------------------------
			//  If I have an inflictor (enemy / grenade) update memory with
			//  position of inflictor, otherwise update with an position
			//  estimate for where the attack came from
			// ------------------------------------------------------
			Vector vAttackPos;
			CEntity *inflictor = CEntity::Instance(info.GetInflictor());
			if (inflictor)
			{
				vAttackPos = inflictor->GetAbsOrigin();
			}
			else
			{
				vAttackPos = (GetAbsOrigin() + ( *g_vecAttackDir * 64 ));
			}


			// ----------------------------------------------------------------
			//  If I already have an enemy, assume that the attack
			//  came from the enemy and update my enemy's position
			//  unless I already know about the attacker or I can see my enemy
			// ----------------------------------------------------------------
			if ( GetEnemy() != NULL							&&
				!GetEnemies()->HasMemory( info.GetAttacker() )			&&
				!HasCondition(COND_SEE_ENEMY)	)
			{
				UpdateEnemyMemory(GetEnemy_CBase(), vAttackPos, GetEnemy_CBase());
			}
			// ----------------------------------------------------------------
			//  If I already know about this enemy, update his position
			// ----------------------------------------------------------------
			else if (GetEnemies()->HasMemory( info.GetAttacker() ))
			{
				UpdateEnemyMemory(info.GetAttacker(), vAttackPos);
			}
			// -----------------------------------------------------------------
			//  Otherwise just note the position, but don't add enemy to my list
			// -----------------------------------------------------------------
			else
			{
				UpdateEnemyMemory(NULL, vAttackPos);
			}
		}

		// add pain to the conditions
		if ( IsLightDamage( info ) )
		{
			SetCondition( COND_LIGHT_DAMAGE );
		}
		if ( IsHeavyDamage( info ) )
		{
			SetCondition( COND_HEAVY_DAMAGE );
		}

		ForceGatherConditions();

		// Keep track of how much consecutive damage I have recieved
		if ((gpGlobals->curtime - m_flLastDamageTime) < 1.0)
		{
			m_flSumDamage += info.GetDamage();
		}
		else
		{
			m_flSumDamage = info.GetDamage();
		}
		m_flLastDamageTime = gpGlobals->curtime;
		if ( attacker && attacker->IsPlayer() )
			m_flLastPlayerDamageTime = gpGlobals->curtime;
		GetEnemies()->OnTookDamageFrom( info.GetAttacker() );

		if (m_flSumDamage > m_iMaxHealth*0.3)
		{
			SetCondition(COND_REPEATED_DAMAGE);
		}
	
		NotifyFriendsOfDamage( info.GetAttacker() );
	}

	// ---------------------------------------------------------------
	//  Insert a combat sound so that nearby NPCs know I've been hit
	// ---------------------------------------------------------------
	g_helpfunc.CSoundEnt_InsertSound(SOUND_COMBAT, GetAbsOrigin(), 1024, 0.5, BaseEntity(), SOUNDENT_CHANNEL_INJURY );
	
	return 1;
}
Exemple #15
0
void CubesGame::LoadContent()
{
	Game::LoadContent();

	World *m_pWorld = NEW_AO World();
	GameInfo::Instance().SetWorld(m_pWorld);

	m_pProgram = Program::loadProgram("vs_mesh", "fs_mesh");

	//Camera 3D
	BaseEntity *pCamera = NEW_AO BaseEntity();
	Camera3DComponent *m_pCamera3D = NEW_AO Camera3DComponent(pCamera);
	ArcBallCameraController *pArcBall = NEW_AO ArcBallCameraController(m_pCamera3D);
	pArcBall->SetCamera(Vector3F(0, 20.0f, -50.0f), Vector3F::Zero(), Vector3F::Up());
	pArcBall->Distance(15.0f);
	m_pCamera3D->CameraController(pArcBall);
	pCamera->GetComponentMgr()->AddComponent(m_pCamera3D);	
	pCamera->Initialize();
	m_pWorld->AddEntity(pCamera);
	GameInfo::Instance().SetActiveCamera(m_pCamera3D);

	const float delta = 3.0f;

	//Box
	BaseEntity* pEntity = NEW_AO BaseEntity();
	pEntity->SetName("box");
	Transform3DComponent *pTransform = NEW_AO Transform3DComponent(pEntity);
	pTransform->SetLocalPosition(Vector3F(0.0f, 0.5f, delta));
	pTransform->SetLocalRotation(0.0f);
	pTransform->SetLocalScale(Vector3F::One());
	pEntity->GetComponentMgr()->AddComponent(pTransform);
	MeshComponent *pModelCpt = NEW_AO MeshComponent(pEntity);
	IPrimitive3D *pPrimitive = NEW_AO BoxPrimitive();
	Mesh *pModel = pPrimitive->CreateModel();
	//ResourceManager::Instance().Add("boxModel", pModel);
	//DELETE_AO pPrimitive;
	pModelCpt->SetModel(pModel);
	pModelCpt->SetProgram(m_pProgram);
	pEntity->GetComponentMgr()->AddComponent(pModelCpt);
	pEntity->Initialize();

	m_pWorld->AddEntity(pEntity);

	//Sphere
	pEntity = NEW_AO BaseEntity();
	pEntity->SetName("sphere");
	pTransform = NEW_AO Transform3DComponent(pEntity);
	pTransform->SetLocalPosition(Vector3F(delta, 0.5f, 0.0f));
	pTransform->SetLocalRotation(0.0f);
	pTransform->SetLocalScale(Vector3F::One());
	pEntity->GetComponentMgr()->AddComponent(pTransform);
	pModelCpt = NEW_AO MeshComponent(pEntity);
	pPrimitive = NEW_AO SpherePrimitive();
	pModel = pPrimitive->CreateModel();
	//ResourceManager::Instance().Add("sphereModel", pModel);
	pModelCpt->SetModel(pModel);
	pModelCpt->SetProgram(m_pProgram);
	//DELETE_AO pPrimitive;
	pEntity->GetComponentMgr()->AddComponent(pModelCpt);
	pEntity->Initialize();

	m_pWorld->AddEntity(pEntity);

	//Cylinder
	pEntity = NEW_AO BaseEntity();
	pEntity->SetName("cylinder");
	pTransform = NEW_AO Transform3DComponent(pEntity);
	pTransform->SetLocalPosition(Vector3F(-delta, 0.5f, 0.0f));
	pTransform->SetLocalRotation(0.0f);
	pTransform->SetLocalScale(Vector3F::One());
	pEntity->GetComponentMgr()->AddComponent(pTransform);
	pModelCpt = NEW_AO MeshComponent(pEntity);
	pPrimitive = NEW_AO CylinderPrimitive();
	pModel = pPrimitive->CreateModel();
	//ResourceManager::Instance().Add("cylinderModel", pModel);
	pModelCpt->SetModel(pModel);
	pModelCpt->SetProgram(m_pProgram);
	//DELETE_AO pPrimitive;
	pEntity->GetComponentMgr()->AddComponent(pModelCpt);
	pEntity->Initialize();

	m_pWorld->AddEntity(pEntity);

	//ground
	pEntity = NEW_AO BaseEntity();
	pEntity->SetName("ground");
	pTransform = NEW_AO Transform3DComponent(pEntity);
	pTransform->SetLocalPosition(Vector3F(0.0f, 0.0f, 0.0f));
	pTransform->SetLocalRotation(0.0f);
	pTransform->SetLocalScale(Vector3F::One());
	pEntity->GetComponentMgr()->AddComponent(pTransform);
	pModelCpt = NEW_AO MeshComponent(pEntity);
	pPrimitive = NEW_AO PlanePrimitive(100.0f, 100.0f);
	pModel = pPrimitive->CreateModel();
	//ResourceManager::Instance().Add("groundModel", pModel);
	//DELETE_AO pPrimitive;
	//new material
	Material* pMat = pModel->GetMaterial()->Clone();
	//ResourceManager::Instance().Add("groundMaterial", pMat);
	pModel->SetMaterial(pMat);
	pMat->Texture0(Texture::loadTexture("ceilingMain_DIF.dds", BGFX_TEXTURE_MIN_ANISOTROPIC | BGFX_TEXTURE_MAG_ANISOTROPIC));
	pMat->Texture0Repeat(Vector2F(50, 50));
	//
	pModelCpt->SetModel(pModel);
	pModelCpt->SetProgram(m_pProgram);
	pEntity->GetComponentMgr()->AddComponent(pModelCpt);
	pEntity->Initialize();

	m_pWorld->AddEntity(pEntity);
}
void CE_Cycler_Fix::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	g_helpfunc.CBaseEntity_Use(BaseEntity(), pActivator, pCaller, useType, value);
}
int CE_Cycler_Fix::OnTakeDamage(const CTakeDamageInfo& info)
{
	return g_helpfunc.CBaseCombatCharacter_OnTakeDamage(BaseEntity(), info);
}
void CE_Cycler_Fix::Precache(void)
{
	g_helpfunc.CAI_BaseNPC_Precache(BaseEntity());

	gm_iszPlayerSquad = AllocPooledString( PLAYER_SQUADNAME );
}
void CFlex::Set_m_flexWeight(int index, float value)
{
	*(float *)(((uint8_t *)(BaseEntity())) + m_flexWeight.offset + (index*4)) = value;
}
//-----------------------------------------------------------------------------
// Purpose: return the index to the shared bone cache
// Output :
//-----------------------------------------------------------------------------
CBoneCache *CAnimating::GetBoneCache( void )
{
	return g_helpfunc.GetBoneCache(BaseEntity());
}
int CE_CBeam::Get_m_nAttachIndex(int index)
{
	return *(int *)(((uint8_t *)(BaseEntity())) + m_nAttachIndex.offset + (index*4));
}
CEntity *CE_CBeam::Get_m_hAttachEntity(int index)
{
	CBaseHandle &hndl = *(CBaseHandle *)(((uint8_t *)(BaseEntity())) + m_hAttachEntity.offset + (index*4));
	return CEntity::Instance(hndl);
}
void CE_CBeam::Set_m_hAttachEntity(int index, CBaseEntity *pEntity)
{
	edict_t *pEdict = servergameents->BaseEntityToEdict(pEntity);
	CBaseHandle &hndl = *(CBaseHandle *)(((uint8_t *)(BaseEntity())) + m_hAttachEntity.offset + (index*4));
	hndl.Set((pEdict) ? pEdict->GetIServerEntity() : NULL);
}
//-----------------------------------------------------------------------------
// Exports CBaseEntity.
//-----------------------------------------------------------------------------
void export_base_entity(scope _entity)
{
	class_<CBaseEntityWrapper, boost::shared_ptr<CBaseEntityWrapper>, bases<IServerEntity>, boost::noncopyable> BaseEntity("BaseEntity", no_init);

	// Initializers...
	BaseEntity.def("__init__",
		make_constructor(
			&CBaseEntityWrapper::__init__,
			default_call_policies(),
			args("entity_index")
		)
	);

	// Properties...
	BaseEntity.add_property("server_class",
		make_function(&CBaseEntityWrapper::GetServerClass, reference_existing_object_policy()),
		"The ServerClass instance of this entity (read-only)."
	);

	BaseEntity.add_property("datamap",
		make_function(&CBaseEntityWrapper::GetDataDescMap, reference_existing_object_policy()),
		"The DataMap instance of this entity (read-only)."
	);

	BaseEntity.add_property("edict", make_function(&CBaseEntityWrapper::GetEdict, reference_existing_object_policy()));
	BaseEntity.add_property("index", &CBaseEntityWrapper::GetIndex);
	BaseEntity.add_property("pointer", make_function(&CBaseEntityWrapper::GetPointer));
	BaseEntity.add_property("inthandle", &CBaseEntityWrapper::GetIntHandle);

	// Methods...
	BaseEntity.def("get_key_value_string",
		&CBaseEntityWrapper::GetKeyValueString,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("get_key_value_int",
		&CBaseEntityWrapper::GetKeyValueInt,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("get_key_value_float",
		&CBaseEntityWrapper::GetKeyValueFloat,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("get_key_value_vector",
		&CBaseEntityWrapper::GetKeyValueVector,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("get_key_value_bool",
		&CBaseEntityWrapper::GetKeyValueBool,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("get_key_value_color",
		&CBaseEntityWrapper::GetKeyValueColor,
		"Returns the value of the given field name.",
		args("field_name")
	);

	BaseEntity.def("set_key_value_int",
		&CBaseEntityWrapper::SetKeyValue<int>,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("set_key_value_float",
		&CBaseEntityWrapper::SetKeyValue<float>,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("set_key_value_string",
		&CBaseEntityWrapper::SetKeyValue<const char *>,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("set_key_value_vector",
		&CBaseEntityWrapper::SetKeyValue<Vector>,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("set_key_value_bool",
		&CBaseEntityWrapper::SetKeyValue<bool>,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("set_key_value_color",
		&CBaseEntityWrapper::SetKeyValueColor,
		"Sets a field to the given value.",
		args("field_name", "value")
	);

	BaseEntity.def("is_player",
		&CBaseEntityWrapper::IsPlayer,
		"Return True if the entity is a player."
	);

	// Add memory tools...
	BaseEntity ADD_MEM_TOOLS(CBaseEntityWrapper);
}
void CE_CBeam::Set_m_nAttachIndex(int index, int value)
{
	*(int *)(((uint8_t *)(BaseEntity())) + m_nAttachIndex.offset + (index*4)) = value;
}
float CFlex::Get_m_flexWeight(int index)
{
	return *(float *)(((uint8_t *)(BaseEntity())) + m_flexWeight.offset + (index*4));
}