//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
int CNPC_CraneDriver::SelectSchedule( void )
{
	if ( HasSpawnFlags(SF_VEHICLEDRIVER_INACTIVE) )
		return BaseClass::SelectSchedule();

	// If we've got an object to pickup, so go get it
	if ( m_hPickupTarget )
	{
		// Only clear the pickup target if we managed to pick something up
		if ( m_hCrane->GetTotalMassOnCrane() > 0 )
		{
			if ( m_bForcedPickup )
			{
				m_OnPickedUpObject.FireOutput( m_hPickupTarget, this );
			}

			// Remember what we dropped so we go try something else if we can.
			m_PreviouslyPickedUpObjects.AddToTail( m_hPickupTarget );
			m_hPickupTarget = NULL;
		}
		else
		{
			if ( m_NPCState == NPC_STATE_IDLE )
			{
				m_IdealNPCState = NPC_STATE_ALERT;
			}
			return SCHED_CRANE_PICKUP_OBJECT;
		}
	}

	// If we're currently being forced to pickup something, do only that
	if ( m_bForcedPickup )
	{
		if ( m_hPickupTarget )
			return SCHED_CRANE_PICKUP_OBJECT;

		// We've picked up our target, we're waiting to be told where to put it
		return SCHED_IDLE_STAND;
	}

	// If we've been told to drop something off, do that
	if ( m_bForcedDropoff )
		return SCHED_CRANE_FORCED_DROP;

	switch ( m_NPCState )
	{
	case NPC_STATE_IDLE:
		break;

	case NPC_STATE_ALERT:
		break;

	case NPC_STATE_COMBAT:
		if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) )
		{
			// Do we have anything on the crane? If not, look for something
			if ( m_hCrane->GetTotalMassOnCrane() == 0 )
				return SCHED_CRANE_FIND_LARGE_OBJECT;

			// We've got something on the crane, so try and drop it on the enemy
			return SCHED_CRANE_RANGE_ATTACK1;
		}

		// We can't attack him, so if we don't have anything on the crane, grab something
		if ( m_hCrane->GetTotalMassOnCrane() == 0 )
			return SCHED_CRANE_FIND_LARGE_OBJECT;
	}

	return BaseClass::SelectSchedule();
}
Пример #2
0
//-----------------------------------------------------------------------------
// Purpose: Input handler for making the explosion explode.
//-----------------------------------------------------------------------------
void CEnvExplosion::InputExplode( inputdata_t &inputdata )
{ 
	trace_t tr;

	SetModelName( NULL_STRING );//invisible
	SetSolid( SOLID_NONE );// intangible

	Vector vecSpot = GetAbsOrigin() + Vector( 0 , 0 , 8 );
	UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -40 ), (MASK_SOLID_BRUSHONLY | MASK_WATER), this, COLLISION_GROUP_NONE, &tr );
	
	// Pull out of the wall a bit. We used to move the explosion origin itself, but that seems unnecessary, not to mention a
	// little weird when you consider that it might be in hierarchy. Instead we just calculate a new virtual position at
	// which to place the explosion. We don't use that new position to calculate radius damage because according to Steve's
	// comment, that adversely affects the force vector imparted on explosion victims when they ragdoll.
	Vector vecExplodeOrigin = GetAbsOrigin();
	if ( tr.fraction != 1.0 )
	{
		vecExplodeOrigin = tr.endpos + (tr.plane.normal * 24 );
	}

	// draw decal
	if (! ( m_spawnflags & SF_ENVEXPLOSION_NODECAL))
	{
		UTIL_DecalTrace( &tr, "Scorch" );
	}

	// It's stupid that this entity's spawnflags and the flags for the
	// explosion temp ent don't match up. But because they don't, we
	// have to reinterpret some of the spawnflags to determine which
	// flags to pass to the temp ent.
	int nFlags = TE_EXPLFLAG_NONE;

	if( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALL )
	{
		nFlags |= TE_EXPLFLAG_NOFIREBALL;
	}
	
	if( m_spawnflags & SF_ENVEXPLOSION_NOSOUND )
	{
		nFlags |= TE_EXPLFLAG_NOSOUND;
	}
	
	if ( m_spawnflags & SF_ENVEXPLOSION_RND_ORIENT )
	{
		nFlags |= TE_EXPLFLAG_ROTATE;
	}

	if ( m_nRenderMode == kRenderTransAlpha )
	{
		nFlags |= TE_EXPLFLAG_DRAWALPHA;
	}
	else if ( m_nRenderMode != kRenderTransAdd )
	{
		nFlags |= TE_EXPLFLAG_NOADDITIVE;
	}

	if( m_spawnflags & SF_ENVEXPLOSION_NOPARTICLES )
	{
		nFlags |= TE_EXPLFLAG_NOPARTICLES;
	}

	if( m_spawnflags & SF_ENVEXPLOSION_NODLIGHTS )
	{
		nFlags |= TE_EXPLFLAG_NODLIGHTS;
	}

	if ( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALLSMOKE )
	{
		nFlags |= TE_EXPLFLAG_NOFIREBALLSMOKE;
	}

	//Get the damage override if specified
	int	iRadius = ( m_iRadiusOverride > 0 ) ? m_iRadiusOverride : ( m_iMagnitude * 2.5f );

	CPASFilter filter( vecExplodeOrigin );
	te->Explosion( filter, 0.0,
		&vecExplodeOrigin, 
		( m_sFireballSprite < 1 ) ? g_sModelIndexFireball : m_sFireballSprite,
		!( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALL ) ? ( m_spriteScale / 10.0 ) : 0.0,
		15,
		nFlags,
		iRadius,
		m_iMagnitude );

	// do damage
	if ( !( m_spawnflags & SF_ENVEXPLOSION_NODAMAGE ) )
	{
		CBaseEntity *pAttacker = GetOwnerEntity() ? GetOwnerEntity() : this;

		// Only calculate damage type if we didn't get a custom one passed in
		int iDamageType = m_iCustomDamageType;
		if ( iDamageType == -1 )
		{
			iDamageType = HasSpawnFlags( SF_ENVEXPLOSION_GENERIC_DAMAGE ) ? DMG_GENERIC : DMG_BLAST;
		}

		CTakeDamageInfo info( m_hInflictor ? m_hInflictor : this, pAttacker, m_iMagnitude, iDamageType );

		if( HasSpawnFlags( SF_ENVEXPLOSION_SURFACEONLY ) )
		{
			info.AddDamageType( DMG_BLAST_SURFACE );
		}

		if ( m_flDamageForce )
		{
			// Not the right direction, but it'll be fixed up by RadiusDamage.
			info.SetDamagePosition( GetAbsOrigin() );
			info.SetDamageForce( Vector( m_flDamageForce, 0, 0 ) );
		}

		RadiusDamage( info, GetAbsOrigin(), iRadius, m_iClassIgnore, m_hEntityIgnore.Get() );
	}

	SetThink( &CEnvExplosion::Smoke );
	SetNextThink( gpGlobals->curtime + 0.3 );

	// Only do these effects if we're not submerged
	if ( UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER )
	{
		// draw sparks
		if ( !( m_spawnflags & SF_ENVEXPLOSION_NOSPARKS ) )
		{
			int sparkCount = random->RandomInt(0,3);

			for ( int i = 0; i < sparkCount; i++ )
			{
				QAngle angles;
				VectorAngles( tr.plane.normal, angles );
				Create( "spark_shower", vecExplodeOrigin, angles, NULL );
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Combine_Cannon::Spawn( void )
{
	Precache();

	/// HACK:
	SetModel( "models/combine_soldier.mdl" );

	// Setup our ancillary beams but keep them hidden for now
	CreateLaser();
	CreateAncillaryBeams();

	m_iAmmoType = GetAmmoDef()->Index( "CombineHeavyCannon" );

	SetHullType( HULL_HUMAN );
	SetHullSizeNormal();

	UTIL_SetSize( this, Vector( -16, -16 , 0 ), Vector( 16, 16, 64 ) );

	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_FLY );
	m_bloodColor		= DONT_BLEED;
	m_iHealth			= 10;
	m_flFieldOfView		= DOT_45DEGREE;
	m_NPCState			= NPC_STATE_NONE;

	if( HasSpawnFlags( SF_STARTDISABLED ) )
	{
		m_fEnabled = false;
	}
	else
	{
		m_fEnabled = true;
	}

	CapabilitiesClear();
	CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_SIMPLE_RADIUS_DAMAGE );

	m_HackedGunPos = Vector ( 0, 0, 0 ); 

	AddSpawnFlags( SF_NPC_LONG_RANGE | SF_NPC_ALWAYSTHINK );

	NPCInit();

	// Limit our look distance
	SetDistLook( m_flSightDist );

	AddEffects( EF_NODRAW );
	AddSolidFlags( FSOLID_NOT_SOLID );

	// Point the cursor straight ahead so that the sniper's
	// first sweep of the laser doesn't look weird.
	Vector vecForward;
	AngleVectors( GetLocalAngles(), &vecForward );
	m_vecPaintCursor = GetBulletOrigin() + vecForward * 1024;

	// none!
	GetEnemies()->SetFreeKnowledgeDuration( 0.0f );
	GetEnemies()->SetEnemyDiscardTime( 2.0f );

	m_flTimeLastAttackedPlayer = 0.0f;
}
Пример #4
0
void CRotButton::Spawn( void )
{
	//----------------------------------------------------
	//determine sounds for buttons
	//a sound of 0 should not make a sound
	//----------------------------------------------------
	if ( m_sounds )
	{
		m_sNoise = MakeButtonSound( m_sounds );
		PrecacheScriptSound(m_sNoise.ToCStr());
	}
	else
	{
		m_sNoise = NULL_STRING;
	}

	// set the axis of rotation
	CBaseToggle::AxisDir();

	// check for clockwise rotation
	if ( HasSpawnFlags( SF_DOOR_ROTATE_BACKWARDS) )
	{
		m_vecMoveAng = m_vecMoveAng * -1;
	}

	SetMoveType( MOVETYPE_PUSH );
	
#ifdef HL1_DLL
	SetSolid( SOLID_BSP );
#else
	SetSolid( SOLID_VPHYSICS );
#endif
	if ( HasSpawnFlags( SF_ROTBUTTON_NOTSOLID ) )
	{
		AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
		AddSolidFlags( FSOLID_NOT_SOLID );
	}

	SetModel( STRING( GetModelName() ) );
	
	if (m_flSpeed == 0)
		m_flSpeed = 40;

	if (m_flWait == 0)
		m_flWait = 1;

	if (m_iHealth > 0)
	{
		m_takedamage = DAMAGE_YES;
	}

	m_toggle_state = TS_AT_BOTTOM;
	m_vecAngle1	= GetLocalAngles();
	m_vecAngle2	= GetLocalAngles() + m_vecMoveAng * m_flMoveDistance;
	ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal\n");

	m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE);
	m_fRotating = TRUE;

	SetUse(&CRotButton::ButtonUse);

	//
	// If touching activates the button, set its touch function.
	//
	if (!HasSpawnFlags(SF_BUTTON_TOUCH_ACTIVATES))
	{
		SetTouch ( NULL );
	}
	else
	{
		SetTouch( &CRotButton::ButtonTouch );
	}

	CreateVPhysics();
}
Пример #5
0
void CAI_ScriptConditions::EvaluationThink()
{
	if ( m_fDisabled == true )
		return;

	int iActorsDone = 0;

	for ( int i = 0; i < m_ElementList.Count(); )
	{
		CAI_ScriptConditionsElement *pConditionElement = &m_ElementList[i];

		if ( pConditionElement == NULL )
		{
			i++;
			continue;
		}

		CBaseEntity *pActor = pConditionElement->GetActor();
		CBaseEntity *pActivator = this;

#ifdef HL2_EPISODIC
		if ( pActor && HasSpawnFlags( SF_ACTOR_AS_ACTIVATOR ) )
		{
			pActivator = pActor;
		}
#endif

		AssertMsg( !m_fDisabled, ("Violated invariant between CAI_ScriptConditions disabled state and think func setting") );

		if ( m_Actor != NULL_STRING && !pActor )
		{
			if ( m_ElementList.Count() == 1 )
			{
				DevMsg( "Warning: Active AI script conditions associated with an non-existant or destroyed NPC\n" );
				m_NoValidActors.FireOutput( this, this, 0 );
			}

			iActorsDone++;
			m_ElementList.Remove( i );
			continue;
		}

		i++;

		if( m_flMinTimeout > 0 && pConditionElement->GetTimeOut()->Expired() )
		{
			ScrCondDbgMsg( ( "%s firing output OnConditionsTimeout (%f seconds)\n", STRING( GetEntityName() ), pConditionElement->GetTimeOut()->GetInterval() ) );

			iActorsDone++;
			m_OnConditionsTimeout.FireOutput( pActivator, this );
			continue;
		}

		bool      result = true;
		const int nEvaluators = sizeof( gm_Evaluators ) / sizeof( gm_Evaluators[0] );

		EvalArgs_t args =
		{
			pActor,
			GetPlayer(),
			m_hTarget.Get()
		};

		for ( int i = 0; i < nEvaluators; ++i )
		{
			if ( !(this->*gm_Evaluators[i].pfnEvaluator)( args ) )
			{
				pConditionElement->GetTimer()->Reset();
				result = false;

				ScrCondDbgMsg( ( "%s failed on: %s\n", GetDebugName(), gm_Evaluators[ i ].pszName ) );

				break;
			}
		}

		if ( result )
		{
			ScrCondDbgMsg( ( "%s waiting... %f\n", GetDebugName(), pConditionElement->GetTimer()->GetRemaining() ) );
		}

		if ( result && pConditionElement->GetTimer()->Expired() )
		{
			ScrCondDbgMsg( ( "%s firing output OnConditionsSatisfied\n", GetDebugName() ) );

			// Default behavior for now, provide worldcraft option later.
			iActorsDone++;
			m_OnConditionsSatisfied.FireOutput( pActivator, this );
		}
	}

	//All done!
	if ( iActorsDone == m_ElementList.Count() )
	{
		Disable();
		m_ElementList.Purge();
	}

	SetThinkTime();
}
//-----------------------------------------------------------------------------
// Purpose: Starts the door going to its "up" position (simply ToggleData->vecPosition2).
//-----------------------------------------------------------------------------
void CBaseDoor::DoorGoUp( void )
{
	edict_t	*pevActivator;

	UpdateAreaPortals( true );
	// It could be going-down, if blocked.
	ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);

	// emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't
	// filter them out and leave a client stuck with looping door sounds!
	if ( !HasSpawnFlags(SF_DOOR_SILENT ) )
	{
		// If we're not moving already, start the moving noise
		if ( m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN )
		{
			StartMovingSound();
		}
	}

	m_toggle_state = TS_GOING_UP;
	
	SetMoveDone( &CBaseDoor::DoorHitTop );
	if ( IsRotatingDoor() )		// !!! BUGBUG Triggered doors don't work with this yet
	{
		float	sign = 1.0;

		if ( m_hActivator != NULL )
		{
			pevActivator = m_hActivator->edict();
			
			if ( !HasSpawnFlags( SF_DOOR_ONEWAY ) && m_vecMoveAng.y ) 		// Y axis rotation, move away from the player
			{
				// Positive is CCW, negative is CW, so make 'sign' 1 or -1 based on which way we want to open.
				// Important note:  All doors face East at all times, and twist their local angle to open.
				//					So you can't look at the door's facing to determine which way to open.

				Vector nearestPoint;
				CollisionProp()->CalcNearestPoint( m_hActivator->GetAbsOrigin(), &nearestPoint );
				Vector activatorToNearestPoint = nearestPoint - m_hActivator->GetAbsOrigin();
				activatorToNearestPoint.z = 0;

				Vector activatorToOrigin = GetAbsOrigin() - m_hActivator->GetAbsOrigin();
				activatorToOrigin.z = 0;

				// Point right hand at door hinge, curl hand towards closest spot on door, if thumb
				// is up, open door CW.  -- Department of Basic Cross Product Understanding for Noobs
				Vector cross = activatorToOrigin.Cross( activatorToNearestPoint );

				if( cross.z > 0.0f )
				{
					sign = -1.0f;	
				}
			}
		}
		AngularMove(m_vecAngle2*sign, m_flSpeed);
	}
	else
	{
		LinearMove(m_vecPosition2, m_flSpeed);
	}

	//Fire our open ouput
	m_OnOpen.FireOutput( this, this );
}
Пример #7
0
void CBaseButton::Spawn( )
{ 
	//----------------------------------------------------
	//determine sounds for buttons
	//a sound of 0 should not make a sound
	//----------------------------------------------------
	if ( m_sounds )
	{
		m_sNoise = MakeButtonSound( m_sounds );
		PrecacheScriptSound(m_sNoise.ToCStr());
	}
	else
	{
		m_sNoise = NULL_STRING;
	}

	Precache();

	if ( HasSpawnFlags( SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state
	{
		SetThink ( &CBaseButton::ButtonSpark );
		SetNextThink( gpGlobals->curtime + 0.5f );// no hurry, make sure everything else spawns
	}

	// Convert movedir from angles to a vector
	QAngle angMoveDir = QAngle( m_vecMoveDir.x, m_vecMoveDir.y, m_vecMoveDir.z );
	AngleVectors( angMoveDir, &m_vecMoveDir );

	SetMoveType( MOVETYPE_PUSH );
	SetSolid( SOLID_BSP );
	SetModel( STRING( GetModelName() ) );
	
	if (m_flSpeed == 0)
	{
		m_flSpeed = 40;
	}

	m_takedamage = DAMAGE_YES;

	if (m_flWait == 0)
	{
		m_flWait = 1;
	}

	if (m_flLip == 0)
	{
		m_flLip = 4;
	}

	m_toggle_state = TS_AT_BOTTOM;
	m_vecPosition1 = GetLocalOrigin();

	// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
	Vector vecButtonOBB = CollisionProp()->OBBSize();
	vecButtonOBB -= Vector( 2, 2, 2 );
	m_vecPosition2	= m_vecPosition1 + (m_vecMoveDir * (DotProductAbs( m_vecMoveDir, vecButtonOBB ) - m_flLip));

	// Is this a non-moving button?
	if ( ((m_vecPosition2 - m_vecPosition1).Length() < 1) || HasSpawnFlags(SF_BUTTON_DONTMOVE) )
	{
		m_vecPosition2 = m_vecPosition1;
	}

	m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE);
	m_fRotating = FALSE;

	if (HasSpawnFlags(SF_BUTTON_LOCKED))
	{
		m_bLocked = true;
	}

	//
	// If using activates the button, set its use function.
	//
	if (HasSpawnFlags(SF_BUTTON_USE_ACTIVATES))
	{
		SetUse(&CBaseButton::ButtonUse);
	}
	else
	{
		SetUse(NULL);
	}

	//
	// If touching activates the button, set its touch function.
	//
	if (HasSpawnFlags(SF_BUTTON_TOUCH_ACTIVATES))
	{
		SetTouch( &CBaseButton::ButtonTouch );
	}
	else 
	{
		SetTouch ( NULL );
	}

	CreateVPhysics();
}
//-----------------------------------------------------------------------------
// Chooses an item when the player is full
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBasePlayer *pPlayer, int iDebug )
{
	// Can we not actually spawn the item?
	if ( !HasSpawnFlags(SF_DYNAMICRESUPPLY_ALWAYS_SPAWN) )
		return;

	float flRatio[NUM_AMMO_ITEMS];
	int i;
	float flTotalProb = 0.0f;
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef );
		bool bCanSpawn = pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) != NULL;

		if ( bCanSpawn && ( g_DynamicResupplyAmmoItems[i].flFullProbability != 0 ) && ( pMaster->m_flDesiredAmmo[i] != 0.0f ) )
		{
			flTotalProb += g_DynamicResupplyAmmoItems[i].flFullProbability;
			flRatio[i] = flTotalProb;
		}
		else
		{
			flRatio[i] = -1.0f;
		}
	}

	if ( flTotalProb == 0.0f )
	{
		// If we're supposed to fallback to just a health vial, do that and finish.
		if ( pMaster->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL) )
		{
			CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning item_healthvial due to spawnflag.\n", g_DynamicResupplyAmmoItems[i].sEntityName );
			}
			return;
		}

		// Otherwise, spawn the first ammo item in the list
		flRatio[0] = 1.0f;
		flTotalProb = 1.0f;
	}
	
	float flChoice = random->RandomFloat( 0.0f, flTotalProb ); 
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		if ( flChoice <= flRatio[i] )
		{
			CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning %s \n", g_DynamicResupplyAmmoItems[i].sEntityName );
			}
			return;
		}
	}

	if ( iDebug )
	{
		Msg("Player is full on all health + ammo, is not spawning.\n" );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Returns whether or not it is OK to make an NPC at this instant.
//-----------------------------------------------------------------------------
bool CBaseNPCMaker::CanMakeNPC( bool bIgnoreSolidEntities )
{
	if( ai_inhibit_spawners.GetBool() )
		return false;

	if ( m_nMaxLiveChildren > 0 && m_nLiveChildren >= m_nMaxLiveChildren )
	{// not allowed to make a new one yet. Too many live ones out right now.
		return false;
	}

	if ( m_iszIngoreEnt != NULL_STRING )
	{
		m_hIgnoreEntity = gEntList.FindEntityByName( NULL, m_iszIngoreEnt );
	}

	Vector mins = GetAbsOrigin() - Vector( 34, 34, 0 );
	Vector maxs = GetAbsOrigin() + Vector( 34, 34, 0 );
	maxs.z = GetAbsOrigin().z;
	
	// If we care about not hitting solid entities, look for 'em
	if ( !bIgnoreSolidEntities )
	{
		CBaseEntity *pList[128];

		int count = UTIL_EntitiesInBox( pList, 128, mins, maxs, FL_CLIENT|FL_NPC );
		if ( count )
		{
			//Iterate through the list and check the results
			for ( int i = 0; i < count; i++ )
			{
				//Don't build on top of another entity
				if ( pList[i] == NULL )
					continue;

				//If one of the entities is solid, then we may not be able to spawn now
				if ( ( pList[i]->GetSolidFlags() & FSOLID_NOT_SOLID ) == false )
				{
					// Since the outer method doesn't work well around striders on account of their huge bounding box.
					// Find the ground under me and see if a human hull would fit there.
					trace_t tr;
					UTIL_TraceHull( GetAbsOrigin() + Vector( 0, 0, 2 ),
									GetAbsOrigin() - Vector( 0, 0, 8192 ),
									NAI_Hull::Mins(HULL_HUMAN),
									NAI_Hull::Maxs(HULL_HUMAN),
									MASK_NPCSOLID,
									m_hIgnoreEntity,
									COLLISION_GROUP_NONE,
									&tr );

					if( !HumanHullFits( tr.endpos + Vector( 0, 0, 1 ) ) )
					{
						return false;
					}
				}
			}
		}
	}

	// Do we need to check to see if the player's looking?
	if ( HasSpawnFlags( SF_NPCMAKER_HIDEFROMPLAYER ) )
	{
		for ( int i = 1; i <= gpGlobals->maxClients; i++ )
		{
			CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
			if ( pPlayer )
			{
				// Only spawn if the player's looking away from me
				if( pPlayer->FInViewCone( GetAbsOrigin() ) && pPlayer->FVisible( GetAbsOrigin() ) )
				{
					if ( !(pPlayer->GetFlags() & FL_NOTARGET) )
						return false;
					DevMsg( 2, "Spawner %s spawning even though seen due to notarget\n", STRING( GetEntityName() ) );
				}
			}
		}
	}

	return true;
}
Пример #10
0
//-----------------------------------------------------------------------------
// Purpose: Called when spawning, after keyvalues have been set.
//-----------------------------------------------------------------------------
void CFuncRotating::Spawn( )
{
#ifdef TF_DLL
	AddSpawnFlags( SF_BRUSH_ROTATE_CLIENTSIDE );
#endif

	//
	// Maintain compatibility with previous maps.
	//
	if (m_flVolume == 0.0)
	{
		m_flVolume = 1.0;
	}

	//
	// If the designer didn't set a sound attenuation, default to one.
	//
	if ( HasSpawnFlags(SF_BRUSH_ROTATE_SMALLRADIUS) )
	{
		m_flAttenuation = ATTN_IDLE;
	}
	else if ( HasSpawnFlags(SF_BRUSH_ROTATE_MEDIUMRADIUS) )
	{
		m_flAttenuation = ATTN_STATIC;
	}
	else if ( HasSpawnFlags(SF_BRUSH_ROTATE_LARGERADIUS) )
	{
		m_flAttenuation = ATTN_NORM;
	}
	else
	{
		m_flAttenuation = ATTN_NORM;
	}

	//
	// Prevent divide by zero if level designer forgets friction!
	//
	if ( m_flFanFriction == 0 )
	{
		m_flFanFriction = 1;
	}
	
	//
	// Build the axis of rotation based on spawnflags.
	//
	if ( HasSpawnFlags(SF_BRUSH_ROTATE_Z_AXIS) )
	{
		m_vecMoveAng = QAngle(0,0,1);
	}
	else if ( HasSpawnFlags(SF_BRUSH_ROTATE_X_AXIS) )
	{
		m_vecMoveAng = QAngle(1,0,0);
	}
	else
	{
		m_vecMoveAng = QAngle(0,1,0);	// y-axis
	}

	//
	// Check for reverse rotation.
	//
	if ( HasSpawnFlags(SF_BRUSH_ROTATE_BACKWARDS) )
	{
		m_vecMoveAng = m_vecMoveAng * -1;
	}

	SetSolid( SOLID_VPHYSICS );

	//
	// Some rotating objects like fake volumetric lights will not be solid.
	//
	if ( HasSpawnFlags(SF_ROTATING_NOT_SOLID) )
	{
		AddSolidFlags( FSOLID_NOT_SOLID );
		SetMoveType( MOVETYPE_PUSH );
	}
	else
	{
		RemoveSolidFlags( FSOLID_NOT_SOLID );
		SetMoveType( MOVETYPE_PUSH );
	}

	SetModel( STRING( GetModelName() ) );

	SetUse( &CFuncRotating::RotatingUse );

	//
	// Did level designer forget to assign a maximum speed? Prevent a divide by
	// zero in RampPitchVol as well as allowing the rotator to work.
	//
	m_flMaxSpeed = fabs( m_flMaxSpeed );
	if (m_flMaxSpeed == 0)
	{
		m_flMaxSpeed = 100;
	}

	//
	// If the brush should be initially rotating, use it in a little while.
	//
	if ( HasSpawnFlags(SF_BRUSH_ROTATE_START_ON) )
	{		
		SetThink( &CFuncRotating::SUB_CallUseToggle );
		SetNextThink( gpGlobals->curtime + .2 );	// leave a magic delay for client to start up
	}

	//
	// Can this brush inflict pain?
	//
	if ( HasSpawnFlags(SF_BRUSH_HURT) )
	{
		SetTouch( &CFuncRotating::HurtTouch );
	}

	//
	// Set speed to 0 in case there's an old "speed" key lying around.
	//
	m_flSpeed = 0;
	
	Precache( );
	CreateVPhysics();

	m_angStart = GetLocalAngles();
	
	// Slam the object back to solid - if we really want it to be solid.
	if ( m_bSolidBsp )
	{
		SetSolid( SOLID_BSP );
	}

	if ( HasSpawnFlags(SF_BRUSH_ROTATE_CLIENTSIDE) )
	{
		m_vecClientOrigin = GetLocalOrigin();
		m_vecClientAngles = GetLocalAngles();
	}
}
Пример #11
0
void CTriggerMomentumPush::EndTouch(CBaseEntity *pOther)
{
    if (pOther && HasSpawnFlags(SF_PUSH_ONEND) && pOther->IsPlayer())
        OnSuccessfulTouch(pOther);
}
Пример #12
0
	bool	IsMaster( void ) const					{ return HasSpawnFlags( SF_TONEMAP_MASTER ); }
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CASW_Broadcast_Camera::FollowTarget( )
{
	//if (m_hPlayer == NULL)
		//return;

	if ( m_hTarget == NULL )
	{
		Disable();
		return;
	}

	if ( !HasSpawnFlags(SF_CAMERA_PLAYER_INFINITE_WAIT) && (!m_hTarget || m_flReturnTime < gpGlobals->curtime) )
	{
		Disable();
		return;
	}

	UpdateAllPlayers();

	QAngle vecGoal;
	if ( m_iAttachmentIndex )
	{
		Vector vecOrigin;
		m_hTarget->GetBaseAnimating()->GetAttachment( m_iAttachmentIndex, vecOrigin );
		VectorAngles( vecOrigin - GetAbsOrigin(), vecGoal );
	}
	else
	{
		if ( m_hTarget )
		{
			VectorAngles( m_hTarget->GetAbsOrigin() - GetAbsOrigin(), vecGoal );
		}
		else
		{
			// Use the viewcontroller's angles
			vecGoal = GetAbsAngles();
		}
	}

	// Should we just snap to the goal angles?
	if ( m_bSnapToGoal ) 
	{
		SetAbsAngles( vecGoal );
		m_bSnapToGoal = false;
	}
	else
	{
		// UNDONE: Can't we just use UTIL_AngleDiff here?
		QAngle angles = GetLocalAngles();

		if (angles.y > 360)
			angles.y -= 360;

		if (angles.y < 0)
			angles.y += 360;

		SetLocalAngles( angles );

		float dx = vecGoal.x - GetLocalAngles().x;
		float dy = vecGoal.y - GetLocalAngles().y;

		if (dx < -180) 
			dx += 360;
		if (dx > 180) 
			dx = dx - 360;
		
		if (dy < -180) 
			dy += 360;
		if (dy > 180) 
			dy = dy - 360;

		QAngle vecAngVel;
		vecAngVel.Init( dx * 40 * gpGlobals->frametime, dy * 40 * gpGlobals->frametime, GetLocalAngularVelocity().z );
		SetLocalAngularVelocity(vecAngVel);
	}

	if (!HasSpawnFlags(SF_CAMERA_PLAYER_TAKECONTROL))	
	{
		SetAbsVelocity( GetAbsVelocity() * 0.8 );
		if (GetAbsVelocity().Length( ) < 10.0)
		{
			SetAbsVelocity( vec3_origin );
		}
	}

	SetNextThink( gpGlobals->curtime );

	Move();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CASW_Broadcast_Camera::Enable( void )
{
	m_state = USE_ON;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	DispatchUpdateTransmitState();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CFuncLadder::Spawn()
{
	BaseClass::Spawn();

	// Entity is symbolid
	SetSolid( SOLID_NONE );
	SetMoveType( MOVETYPE_NONE );
	SetCollisionGroup( COLLISION_GROUP_NONE );
	
	//AddFlag( FL_WORLDBRUSH );
	SetModelName( NULL_STRING );

	// Make entity invisible
	AddEffects( EF_NODRAW );
	// No model but should still network
	AddEFlags( EFL_FORCE_CHECK_TRANSMIT );

	Vector playerMins = VEC_HULL_MIN;
	Vector playerMaxs = VEC_HULL_MAX;

	// This will swap them if they are inverted
	SetEndPoints( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionBottom );

#if !defined( CLIENT_DLL )
	trace_t bottomtrace, toptrace;
	UTIL_TraceHull( m_vecPlayerMountPositionBottom, m_vecPlayerMountPositionBottom, 
		playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &bottomtrace );
	UTIL_TraceHull( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionTop, 
		playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &toptrace );

	if ( bottomtrace.startsolid || toptrace.startsolid )
	{
		if ( bottomtrace.startsolid )
		{
			DevMsg( 1, "Warning, funcladder with blocked bottom point (%.2f %.2f %.2f) stuck in (%s)\n",
				m_vecPlayerMountPositionBottom.GetX(),
				m_vecPlayerMountPositionBottom.GetY(),
				m_vecPlayerMountPositionBottom.GetZ(),
				bottomtrace.m_pEnt 
					? 
					UTIL_VarArgs( "%s/%s", bottomtrace.m_pEnt->GetClassname(), bottomtrace.m_pEnt->GetEntityName().ToCStr() ) 
					//UTIL_VarArgs( "%s/%s", bottomtrace.m_pEnt->GetClassname(), STRING(bottomtrace.m_pEnt->GetEntityName()) ) ?
					: 
					"NULL" );
		}
		if ( toptrace.startsolid )
		{
			DevMsg( 1, "Warning, funcladder with blocked top point (%.2f %.2f %.2f) stuck in (%s)\n",
				m_vecPlayerMountPositionTop.GetX(),
				m_vecPlayerMountPositionTop.GetY(),
				m_vecPlayerMountPositionTop.GetZ(),
				toptrace.m_pEnt 
					? 
					UTIL_VarArgs( "%s/%s", toptrace.m_pEnt->GetClassname(), toptrace.m_pEnt->GetEntityName().ToCStr() ) 
					//UTIL_VarArgs( "%s/%s", toptrace.m_pEnt->GetClassname(), STRING(toptrace.m_pEnt->GetEntityName()) ) ?
					: 
					"NULL" );
		}

		// Force geometry overlays on, but only if developer 2 is set...
		if ( developer.GetInt() > 1 )
		{
			m_debugOverlays |= OVERLAY_TEXT_BIT;
		}
	}

	m_vecPlayerMountPositionTop -= GetAbsOrigin();
	m_vecPlayerMountPositionBottom -= GetAbsOrigin();

	// Compute mins, maxs of points
	// 
	Vector mins( MAX_COORD_INTEGER, MAX_COORD_INTEGER, MAX_COORD_INTEGER );
	Vector maxs( -MAX_COORD_INTEGER, -MAX_COORD_INTEGER, -MAX_COORD_INTEGER );
	int i;
	for ( i = 0; i < 3; i++ )
	{
		if ( m_vecPlayerMountPositionBottom.m_Value[ i ] < mins[ i ] )
		{
			mins[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ];
		}
		if ( m_vecPlayerMountPositionBottom.m_Value[ i ] > maxs[ i ] )
		{
			maxs[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ];
		}
		if ( m_vecPlayerMountPositionTop.m_Value[ i ] < mins[ i ] )
		{
			mins[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ];
		}
		if ( m_vecPlayerMountPositionTop.m_Value[ i ] > maxs[ i ] )
		{
			maxs[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ];
		}
	}

	// Expand mins/maxs by player hull size
	mins += playerMins;
	maxs += playerMaxs;

	UTIL_SetSize( this, mins, maxs );

	m_bFakeLadder = HasSpawnFlags(SF_LADDER_DONTGETON);
#endif
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTemplateNPCMaker::MakeNPC( void )
{
	// If we should be using the radius spawn method instead, do so
	if ( m_flRadius && HasSpawnFlags(SF_NPCMAKER_ALWAYSUSERADIUS) )
	{
		MakeNPCInRadius();
		return;
	}

	if (!CanMakeNPC( ( m_iszDestinationGroup != NULL_STRING ) ))
		return;

	CNPCSpawnDestination *pDestination = NULL;
	if ( m_iszDestinationGroup != NULL_STRING )
	{
		pDestination = FindSpawnDestination();
		if ( !pDestination )
		{
			DevMsg( 2, "%s '%s' failed to find a valid spawnpoint in destination group: '%s'\n", GetClassname(), STRING(GetEntityName()), STRING(m_iszDestinationGroup) );
			return;
		}
	}

	CAI_BaseNPC	*pent = NULL;
	CBaseEntity *pEntity = NULL;
	MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL );
	if ( pEntity != NULL )
	{
		pent = (CAI_BaseNPC *)pEntity;
	}

	if ( !pent )
	{
		Warning("NULL Ent in NPCMaker!\n" );
		return;
	}
	
	if ( pDestination )
	{
		pent->SetAbsOrigin( pDestination->GetAbsOrigin() );

		// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
		QAngle angles = pDestination->GetAbsAngles();
		angles.x = 0.0;
		angles.z = 0.0;
		pent->SetAbsAngles( angles );

		pDestination->OnSpawnedNPC( pent );
	}
	else
	{
		pent->SetAbsOrigin( GetAbsOrigin() );

		// Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC.
		QAngle angles = GetAbsAngles();
		angles.x = 0.0;
		angles.z = 0.0;
		pent->SetAbsAngles( angles );
	}

	m_OnSpawnNPC.Set( pEntity, pEntity, this );

	if ( m_spawnflags & SF_NPCMAKER_FADE )
	{
		pent->AddSpawnFlags( SF_NPC_FADE_CORPSE );
	}

	pent->RemoveSpawnFlags( SF_NPC_TEMPLATE );

	if ( ( m_spawnflags & SF_NPCMAKER_NO_DROP ) == false )
	{
		pent->RemoveSpawnFlags( SF_NPC_FALL_TO_GROUND ); // don't fall, slam
	}

	ChildPreSpawn( pent );

	DispatchSpawn( pent );
	pent->SetOwnerEntity( this );
	DispatchActivate( pent );

	ChildPostSpawn( pent );

	m_nLiveChildren++;// count this NPC

	if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD))
	{
		m_nMaxNumNPCs--;

		if ( IsDepleted() )
		{
			m_OnAllSpawned.FireOutput( this, this );

			// Disable this forever.  Don't kill it because it still gets death notices
			SetThink( NULL );
			SetUse( NULL );
		}
	}
}
Пример #17
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseDoor::Spawn()
{
	Precache();

#ifdef HL1_DLL
	SetSolid( SOLID_BSP );
#else
	if ( GetMoveParent() && GetRootMoveParent()->GetSolid() == SOLID_BSP )
	{
		SetSolid( SOLID_BSP );
	}
	else
	{
		SetSolid( SOLID_VPHYSICS );
	}
#endif

	// Convert movedir from angles to a vector
	QAngle angMoveDir = QAngle( m_vecMoveDir.x, m_vecMoveDir.y, m_vecMoveDir.z );
	AngleVectors( angMoveDir, &m_vecMoveDir );

	SetModel( STRING( GetModelName() ) );
	m_vecPosition1	= GetLocalOrigin();

	// Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big
	Vector vecOBB = CollisionProp()->OBBSize();
	vecOBB -= Vector( 2, 2, 2 );
	m_vecPosition2	= m_vecPosition1 + (m_vecMoveDir * (DotProductAbs( m_vecMoveDir, vecOBB ) - m_flLip));

	if ( !IsRotatingDoor() )
	{
		if ( ( m_eSpawnPosition == FUNC_DOOR_SPAWN_OPEN ) || HasSpawnFlags( SF_DOOR_START_OPEN_OBSOLETE ) )
		{	// swap pos1 and pos2, put door at pos2
			UTIL_SetOrigin( this, m_vecPosition2);
			m_toggle_state = TS_AT_TOP;
		}
		else
		{
			m_toggle_state = TS_AT_BOTTOM;
		}
	}

	if (HasSpawnFlags(SF_DOOR_LOCKED))
	{
		m_bLocked = true;
	}

	SetMoveType( MOVETYPE_PUSH );
	
	if (m_flSpeed == 0)
	{
		m_flSpeed = 100;
	}
	
	SetTouch( &CBaseDoor::DoorTouch );

	if ( !FClassnameIs( this, "func_water" ) )
	{
		if ( HasSpawnFlags(SF_DOOR_PASSABLE) )
		{
			//normal door
			AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
			AddSolidFlags( FSOLID_NOT_SOLID );
		}

		if ( HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) )
		{
			SetCollisionGroup( COLLISION_GROUP_PASSABLE_DOOR );
			// HACKHACK: Set this hoping that any children of the door that get blocked by the player
			// will get fixed up by vphysics
			// NOTE: We could decouple this as a separate behavior, but managing player collisions is already complex enough.
			// NOTE: This is necessary to prevent the player from blocking the wrecked train car in ep2_outland_01
			AddFlag( FL_UNBLOCKABLE_BY_PLAYER );
		}
		if ( m_bIgnoreDebris )
		{
			// both of these flags want to set the collision group and 
			// there isn't a combo group
			Assert( !HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) );
			if ( HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) )
			{
				Warning("Door %s with conflicting collision settings, removing ignoredebris\n", GetDebugName() );
			}
			else
			{
				SetCollisionGroup( COLLISION_GROUP_INTERACTIVE );
			}
		}
	}

	if ( ( m_eSpawnPosition == FUNC_DOOR_SPAWN_OPEN ) && HasSpawnFlags( SF_DOOR_START_OPEN_OBSOLETE ) )
	{
		Warning("Door %s using obsolete 'Start Open' spawnflag with 'Spawn Position' set to 'Open'. Reverting to old behavior.\n", GetDebugName() );
	}

	CreateVPhysics();
}
Пример #18
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &info - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info )
{
	// Don't bother if we've been told not to, or the player has a megaphyscannon
	if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() )
	{
		BaseClass::Event_Killed( info );
		return;
	}

	CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() );

	if ( !pPlayer )
	{
		CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ;
		if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() )
		{
			pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() );
		}
	}

	if ( pPlayer != NULL )
	{
		// Elites drop alt-fire ammo, so long as they weren't killed by dissolving.
		if( IsElite() )
		{
#ifdef HL2_EPISODIC
			if ( HasSpawnFlags( SF_COMBINE_NO_AR2DROP ) == false )
#endif
			{
				CBaseEntity *pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );

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

					if ( pObj )
					{
						Vector			vel		= RandomVector( -64.0f, 64.0f );
						AngularImpulse	angImp	= RandomAngularImpulse( -300.0f, 300.0f );

						vel[2] = 0.0f;
						pObj->AddVelocity( &vel, &angImp );
					}

					if( info.GetDamageType() & DMG_DISSOLVE )
					{
						CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem);

						if( pAnimating )
						{
							pAnimating->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL );
						}
					}
					else
					{
						WeaponManager_AddManaged( pItem );
					}
				}
			}
		}
#ifdef HL2_DLL
		CHalfLife2 *pGameRules = static_cast<CHalfLife2 *>(g_pGameRules);
#elif defined(TF_CLASSIC)
		CTFGameRules *pGameRules = TFGameRules();
#endif
		// Attempt to drop health
		if ( pGameRules->NPC_ShouldDropHealth( pPlayer ) )
		{
			DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );
			pGameRules->NPC_DroppedHealth();
		}
		// Don't drop grenades in TF2C, TF2 players don't need that.
#ifndef TF_CLASSIC
		if ( HasSpawnFlags( SF_COMBINE_NO_GRENADEDROP ) == false )
		{
			// Attempt to drop a grenade
			if ( pGameRules->NPC_ShouldDropGrenade( pPlayer ) )
			{
				DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );
				pGameRules->NPC_DroppedGrenade();
			}
		}
#endif
	}
	BaseClass::Event_Killed( info );
}
Пример #19
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pActivator - 
//			pCaller - 
//			useType - 
//			value - 
//-----------------------------------------------------------------------------
void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if ( m_bDisabled == true )
		return;

	if (m_bLocked)
	{
		if ( OnUseLocked( pActivator ) && HasSpawnFlags( SF_BUTTON_JIGGLE_ON_USE_LOCKED ) )
		{
			// Jiggle two degrees.
			float flDist = 2.0 / m_flMoveDistance;

			// Must be first!
			g_EventQueue.AddEvent( this, "_DisableUpdateTarget", 0, this, this );

			variant_t value;
			value.SetFloat( flDist );
			g_EventQueue.AddEvent( this, "SetPosition", value, 0.01, this, this );

			value.SetFloat( 0.0 );
			g_EventQueue.AddEvent( this, "SetPosition", value, 0.1, this, this );

			value.SetFloat( 0.5 * flDist );
			g_EventQueue.AddEvent( this, "SetPosition", value, 0.2, this, this );

			value.SetFloat( 0.0 );
			g_EventQueue.AddEvent( this, "SetPosition", value, 0.3, this, this );

			// Must be last! And must be late enough to cover the settling time.
			g_EventQueue.AddEvent( this, "_EnableUpdateTarget", 0.5, this, this );
		}

		return;
	}

	//
	// Reverse our direction and play movement sound every time the player
	// pauses between uses.
	//
	bool bPlaySound = false;
	
	if ( !m_lastUsed )
	{
		bPlaySound = true;
		m_direction = -m_direction;

		//Alert that we've been pressed
		m_OnPressed.FireOutput( m_hActivator, this );
	}

	m_lastUsed = 1;

	float flPos = GetPos( GetLocalAngles() );
	UpdateSelf( flPos, bPlaySound );

	//
	// Think every frame while we are moving.
	// HACK: Don't reset the think time if we already have a pending think.
	// This works around an issue with host_thread_mode > 0 when the player's
	// clock runs ahead of the server.
	//
	if ( !m_pfnThink )
	{
		SetThink( &CMomentaryRotButton::UpdateThink );
		SetNextThink( gpGlobals->curtime );
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &info - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CNPC_CombineAce::Event_Killed( const CTakeDamageInfo &info )
{
	if (!(g_Language.GetInt() == LANGUAGE_GERMAN || UTIL_IsLowViolence()) && info.GetDamageType() & (DMG_BLAST | DMG_CRUSH) && !(info.GetDamageType() & (DMG_DISSOLVE)) && !PlayerHasMegaPhysCannon())
	{
		Vector vecDamageDir = info.GetDamageForce();
		SpawnBlood(GetAbsOrigin(), g_vecAttackDir, BloodColor(), info.GetDamage());
		DispatchParticleEffect("headshotspray", GetAbsOrigin(), GetAbsAngles(), this);
		EmitSound("Gore.Headshot");
		float flFadeTime = 25.0;

		CGib::SpawnSpecificGibs(this, 1, 750, 1500, "models/gibs/soldier_ace_head.mdl", flFadeTime);

		Vector vecRagForce;
		vecRagForce.x = random->RandomFloat(-400, 400);
		vecRagForce.y = random->RandomFloat(-400, 400);
		vecRagForce.z = random->RandomFloat(0, 250);

		Vector vecRagDmgForce = (vecRagForce + vecDamageDir);

		CBaseEntity *pLeftArmGib = CreateRagGib("models/gibs/soldier_ace_left_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pLeftArmGib)
		{
			color32 color = pLeftArmGib->GetRenderColor();
			pLeftArmGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pRightArmGib = CreateRagGib("models/gibs/soldier_ace_right_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pRightArmGib)
		{
			color32 color = pRightArmGib->GetRenderColor();
			pRightArmGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pTorsoGib = CreateRagGib("models/gibs/soldier_ace_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pTorsoGib)
		{
			color32 color = pTorsoGib->GetRenderColor();
			pTorsoGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pPelvisGib = CreateRagGib("models/gibs/soldier_ace_pelvis.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pPelvisGib)
		{
			color32 color = pPelvisGib->GetRenderColor();
			pPelvisGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pLeftLegGib = CreateRagGib("models/gibs/soldier_ace_left_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pLeftLegGib)
		{
			color32 color = pLeftLegGib->GetRenderColor();
			pLeftLegGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pRightLegGib = CreateRagGib("models/gibs/soldier_ace_right_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pRightLegGib)
		{
			color32 color = pRightLegGib->GetRenderColor();
			pRightLegGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		//now add smaller gibs.
		CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p3.mdl", flFadeTime);
		CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p4.mdl", flFadeTime);

		if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0)
		{
			pArmor->Remove();
			DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360));
		}

		Vector forceVector = CalcDamageForceVector(info);

		// Drop any weapon that I own
		if (VPhysicsGetObject())
		{
			Vector weaponForce = forceVector * VPhysicsGetObject()->GetInvMass();
			Weapon_Drop(m_hActiveWeapon, NULL, &weaponForce);
		}
		else
		{
			Weapon_Drop(m_hActiveWeapon);
		}

		if (info.GetAttacker()->IsPlayer())
		{
			((CSingleplayRules*)GameRules())->NPCKilled(this, info);
		}

		UTIL_Remove(this);
		SetThink(NULL);
		return;
	}

	// Don't bother if we've been told not to, or the player has a megaphyscannon
	if ( combine_ace_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() )
	{
		BaseClass::Event_Killed( info );
		return;
	}

	SetEyeState(ACE_EYE_DEAD);

	if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0)
	{
		pArmor->Remove();
	}

	CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() );

	if ( !pPlayer )
	{
		CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ;
		if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() )
		{
			pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() );
		}
	}

	if ( pPlayer != NULL )
	{
		// Elites drop alt-fire ammo, so long as they weren't killed by dissolving.
#ifdef HL2_EPISODIC
		if (HasSpawnFlags(SF_COMBINE_NO_AR2DROP) == false)
#endif
		{
			if (FClassnameIs(GetActiveWeapon(), "weapon_ar2"))
			{
				CBaseEntity *pItem = DropItem("item_ammo_ar2_altfire", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360));

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

					if (pObj)
					{
						Vector			vel = RandomVector(-64.0f, 64.0f);
						AngularImpulse	angImp = RandomAngularImpulse(-300.0f, 300.0f);

						vel[2] = 0.0f;
						pObj->AddVelocity(&vel, &angImp);
					}

					if (info.GetDamageType() & DMG_DISSOLVE)
					{
						CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem);

						if (pAnimating)
						{
							pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL);
						}
					}
					else
					{
						WeaponManager_AddManaged(pItem);
					}
				}
			}
			else if (FClassnameIs(GetActiveWeapon(), "weapon_smg1"))
			{
				CBaseEntity *pItem = DropItem("item_ammo_smg1_grenade", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360));

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

					if (pObj)
					{
						Vector			vel = RandomVector(-64.0f, 64.0f);
						AngularImpulse	angImp = RandomAngularImpulse(-300.0f, 300.0f);

						vel[2] = 0.0f;
						pObj->AddVelocity(&vel, &angImp);
					}

					if (info.GetDamageType() & DMG_DISSOLVE)
					{
						CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem);

						if (pAnimating)
						{
							pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL);
						}
					}
					else
					{
						WeaponManager_AddManaged(pItem);
					}
				}
			}
		}

		CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules);

		// Attempt to drop health
		if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) )
		{
			DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );
			pHL2GameRules->NPC_DroppedHealth();
		}

		if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0)
		{
			DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360));
		}
	}

	BaseClass::Event_Killed( info );
}
Пример #21
0
//-----------------------------------------------------------------------------
// Purpose: Enables or disables the use capability based on our spawnflags.
//-----------------------------------------------------------------------------
int	CBaseButton::ObjectCaps(void)
{
	return((BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) |
			(HasSpawnFlags(SF_BUTTON_USE_ACTIVATES) ? (FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS) : 0));
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_CombineAce::Spawn( void )
{
	Precache();

	SetModel( "models/combine_ace_soldier.mdl" );

	//Give him a random amount of grenades on spawn
	if (combine_ace_spawnwithgrenades.GetBool())
	{
		if (g_pGameRules->IsSkillLevel(SKILL_HARD))
		{
			m_iNumGrenades = random->RandomInt(2, 3);
		}
		else if (g_pGameRules->IsSkillLevel(SKILL_VERYHARD))
		{
			m_iNumGrenades = random->RandomInt(4, 6);
		}
		else if (g_pGameRules->IsSkillLevel(SKILL_NIGHTMARE))
		{
			m_iNumGrenades = random->RandomInt(8, 12);
		}
		else
		{
			m_iNumGrenades = random->RandomInt(0, 2);
		}
	}

	m_fIsElite = true;
	m_fIsAce = true;

	// Stronger, tougher.
	SetHealth(sk_combine_ace_health.GetFloat());
	SetMaxHealth(sk_combine_ace_health.GetFloat());
	SetKickDamage(sk_combine_ace_kick.GetFloat());

	CapabilitiesAdd( bits_CAP_ANIMATEDFACE );
	CapabilitiesAdd( bits_CAP_MOVE_SHOOT );
	CapabilitiesAdd( bits_CAP_MOVE_JUMP );
	CapabilitiesAdd( bits_CAP_DOORS_GROUP );

	int attachment = LookupAttachment("eyes");

	// Start up the eye glow
	m_pEyeSprite = CSprite::SpriteCreate("sprites/redglow1.vmt", GetLocalOrigin(), false);

	if (m_pEyeSprite != NULL)
	{
		m_pEyeSprite->SetAttachment(this, attachment);
		m_pEyeSprite->SetTransparency(kRenderTransAdd, 255, 255, 255, 200, kRenderFxNone);
		m_pEyeSprite->SetScale(0.25f);
	}

	// Start up the eye trail
	m_pEyeTrail = CSpriteTrail::SpriteTrailCreate("sprites/bluelaser1.vmt", GetLocalOrigin(), false);

	if (m_pEyeTrail != NULL)
	{
		m_pEyeTrail->SetAttachment(this, attachment);
		m_pEyeTrail->SetTransparency(kRenderTransAdd, 255, 0, 0, 200, kRenderFxNone);
		m_pEyeTrail->SetStartWidth(8.0f);
		m_pEyeTrail->SetLifeTime(0.75f);
	}

	SetEyeState(ACE_EYE_DORMANT);

	if (combine_ace_shieldspawnmode.GetInt() == 1)
	{
		SpawnArmorPieces();
	}
	else if (combine_ace_shieldspawnmode.GetInt() > 1)
	{
		int iShieldRandom = random->RandomInt(0, 3);
		if (iShieldRandom == 0)
		{
			SpawnArmorPieces();
		}
		else
		{
			pArmor = NULL;
			m_bNoArmor = true;
		}
	}
	else
	{
		pArmor = NULL;
		m_bNoArmor = true;
	}

	BaseClass::Spawn();

#if HL2_EPISODIC
	if (m_iUseMarch && !HasSpawnFlags(SF_NPC_START_EFFICIENT))
	{
		Msg( "Soldier %s is set to use march anim, but is not an efficient AI. The blended march anim can only be used for dead-ahead walks!\n", GetDebugName() );
	}
#endif
}
Пример #23
0
//-----------------------------------------------------------------------------
// Purpose: Called when spawning, after keyvalues have been handled.
//-----------------------------------------------------------------------------
void CMomentaryRotButton::Spawn( void )
{
	CBaseToggle::AxisDir();

	m_bUpdateTarget = true;

	if ( m_flSpeed == 0 )
	{
		m_flSpeed = 100;
	}

	// Clamp start position and issue bounds warning
	if (m_flStartPosition < 0.0 || m_flStartPosition > 1.0)
	{
		Warning("WARNING: Momentary door (%s) start position not between 0 and 1.  Clamping.\n",GetDebugName());
		m_flStartPosition = clamp(m_IdealYaw, 0, 1);
	}

	// Check direction fields (for backward compatibility)
	if (m_direction != 1 && m_direction != -1)
	{
		m_direction = 1;
	}

	if (m_flMoveDistance < 0)
	{
		m_vecMoveAng = m_vecMoveAng * -1;
		m_flMoveDistance = -m_flMoveDistance;
	}

	m_start = GetLocalAngles() - m_vecMoveAng * m_flMoveDistance * m_flStartPosition;
	m_end	= GetLocalAngles() + m_vecMoveAng * m_flMoveDistance * (1-m_flStartPosition);

	m_IdealYaw			= m_flStartPosition;

	// Force start direction at end points
	if (m_flStartPosition == 0.0)
	{
		m_direction = -1;
	}
	else if (m_flStartPosition == 1.0)
	{
		m_direction = 1;
	}

	if (HasSpawnFlags(SF_BUTTON_LOCKED))
	{
		m_bLocked = true;
	}

	if ( HasSpawnFlags( SF_BUTTON_USE_ACTIVATES ) )
	{
		if ( m_sounds )
		{
			m_sNoise = MakeButtonSound( m_sounds );
			PrecacheScriptSound(m_sNoise.ToCStr());
		}
		else
		{
			m_sNoise = NULL_STRING;
		}

		m_lastUsed	= 0;
		UpdateTarget(0,this);
	}

#ifdef HL1_DLL
	SetSolid( SOLID_BSP );
#else
	SetSolid( SOLID_VPHYSICS );
#endif
	if (HasSpawnFlags(SF_ROTBUTTON_NOTSOLID))
	{
		AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
		AddSolidFlags( FSOLID_NOT_SOLID );
	}

	SetMoveType( MOVETYPE_PUSH );
	SetModel( STRING( GetModelName() ) );
	
	CreateVPhysics();

	// Slam the object back to solid - if we really want it to be solid.
	if ( m_bSolidBsp )
	{
		SetSolid( SOLID_BSP );
	}

	m_bDisabled = false;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &info - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info )
{
	if (!(g_Language.GetInt() == LANGUAGE_GERMAN || UTIL_IsLowViolence()) && info.GetDamageType() & (DMG_BLAST | DMG_CRUSH) && !(info.GetDamageType() & (DMG_DISSOLVE)) && !PlayerHasMegaPhysCannon())
	{
		Vector vecDamageDir = info.GetDamageForce();
		SpawnBlood(GetAbsOrigin(), g_vecAttackDir, BloodColor(), info.GetDamage());
		DispatchParticleEffect("headshotspray", GetAbsOrigin(), GetAbsAngles(), this);
		EmitSound("Gore.Headshot");
		float flFadeTime = 25.0;

		CGib::SpawnSpecificGibs(this, 1, 750, 1500, "models/gibs/soldier_head.mdl", flFadeTime);
		
		Vector vecRagForce;
		vecRagForce.x = random->RandomFloat(-400, 400);
		vecRagForce.y = random->RandomFloat(-400, 400);
		vecRagForce.z = random->RandomFloat(0, 250);

		Vector vecRagDmgForce = (vecRagForce + vecDamageDir);

		CBaseEntity *pLeftArmGib = CreateRagGib("models/gibs/soldier_left_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pLeftArmGib)
		{ 
			color32 color = pLeftArmGib->GetRenderColor();
			pLeftArmGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pRightArmGib = CreateRagGib("models/gibs/soldier_right_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pRightArmGib)
		{
			color32 color = pRightArmGib->GetRenderColor();
			pRightArmGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pTorsoGib = CreateRagGib("models/gibs/soldier_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pTorsoGib)
		{
			color32 color = pTorsoGib->GetRenderColor();
			pTorsoGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pPelvisGib = CreateRagGib("models/gibs/soldier_pelvis.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pPelvisGib)
		{
			color32 color = pPelvisGib->GetRenderColor();
			pPelvisGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pLeftLegGib = CreateRagGib("models/gibs/soldier_left_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pLeftLegGib)
		{
			color32 color = pLeftLegGib->GetRenderColor();
			pLeftLegGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		CBaseEntity *pRightLegGib = CreateRagGib("models/gibs/soldier_right_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire());
		if (pRightLegGib)
		{
			color32 color = pRightLegGib->GetRenderColor();
			pRightLegGib->SetRenderColor(color.r, color.g, color.b, color.a);
		}

		//now add smaller gibs.
		CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p3.mdl", flFadeTime);
		CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p4.mdl", flFadeTime);

		Vector forceVector = CalcDamageForceVector(info);

		// Drop any weapon that I own
		if (VPhysicsGetObject())
		{
			Vector weaponForce = forceVector * VPhysicsGetObject()->GetInvMass();
			Weapon_Drop(m_hActiveWeapon, NULL, &weaponForce);
		}
		else
		{
			Weapon_Drop(m_hActiveWeapon);
		}

		if (info.GetAttacker()->IsPlayer())
		{
			((CSingleplayRules*)GameRules())->NPCKilled(this, info);
		}

		UTIL_Remove(this);
		SetThink(NULL);
		return;
	}

	// Don't bother if we've been told not to, or the player has a megaphyscannon
	if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() )
	{
		BaseClass::Event_Killed( info );
		return;
	}

	CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() );

	if ( !pPlayer )
	{
		CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ;
		if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() )
		{
			pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() );
		}
	}

	if ( pPlayer != NULL )
	{
		CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules);

		// Attempt to drop health
		if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) )
		{
			DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );
			pHL2GameRules->NPC_DroppedHealth();
		}
		
		if ( HasSpawnFlags( SF_COMBINE_NO_GRENADEDROP ) == false )
		{
			// Attempt to drop a grenade
			if ( pHL2GameRules->NPC_ShouldDropGrenade( pPlayer ) )
			{
				DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) );
				pHL2GameRules->NPC_DroppedGrenade();
			}
		}
	}

	BaseClass::Event_Killed( info );
}
Пример #25
0
//-----------------------------------------------------------------------------
// Purpose: Catches the monster-specific events that occur when tagged animation
//			frames are played.
// Input  : pEvent - 
//-----------------------------------------------------------------------------
void CNPC_PoisonZombie::HandleAnimEvent( animevent_t *pEvent )
{
	
	if ( pEvent->event == AE_ZOMBIE_POISON_PICKUP_CRAB )
	{
		EnableCrab( m_nThrowCrab, false );
		SetBodygroup( ZOMBIE_BODYGROUP_THROW, 1 );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_WARN_SOUND )
	{
		BreatheOffShort();
		EmitSound( "NPC_PoisonZombie.ThrowWarn" );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_SOUND )
	{
		BreatheOffShort();
		EmitSound( "NPC_PoisonZombie.Throw" );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_THROW_CRAB )
	{
		SetBodygroup( ZOMBIE_BODYGROUP_THROW, 0 );

		CBlackHeadcrab *pCrab = (CBlackHeadcrab *)CreateNoSpawn( GetHeadcrabClassname(), EyePosition(), vec3_angle, this );
		pCrab->AddSpawnFlags( SF_NPC_FALL_TO_GROUND );
		
		// Fade if our parent is supposed to
		if ( HasSpawnFlags( SF_NPC_FADE_CORPSE ) )
		{
			pCrab->AddSpawnFlags( SF_NPC_FADE_CORPSE );
		}

		// make me the crab's owner to avoid collision issues
		pCrab->SetOwnerEntity( this );

		pCrab->Spawn();

		pCrab->SetLocalAngles( GetLocalAngles() );
		pCrab->SetActivity( ACT_RANGE_ATTACK1 );
		pCrab->SetNextThink( gpGlobals->curtime );
		pCrab->PhysicsSimulate();

		pCrab->GetMotor()->SetIdealYaw( GetAbsAngles().y );

		if ( IsOnFire() )
		{
			pCrab->Ignite( 100.0 );
		}

		CBaseEntity *pEnemy = GetEnemy();
		if ( pEnemy )
		{
			Vector vecEnemyEyePos = pEnemy->EyePosition();
			pCrab->ThrowAt( vecEnemyEyePos );
		}

		if (m_nCrabCount == 0)
		{
			CapabilitiesRemove( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_RANGE_ATTACK2 );
		}

		m_flNextCrabThrowTime = gpGlobals->curtime + random->RandomInt( ZOMBIE_THROW_MIN_DELAY, ZOMBIE_THROW_MAX_DELAY );
		return;
	}

	if ( pEvent->event == AE_ZOMBIE_POISON_SPIT )
	{
		Vector forward;
		QAngle qaPunch( 45, random->RandomInt(-5, 5), random->RandomInt(-5, 5) );
		AngleVectors( GetLocalAngles(), &forward );
		forward = forward * 200;
		ClawAttack( GetClawAttackRange(), sk_zombie_poison_dmg_spit.GetFloat(), qaPunch, forward, ZOMBIE_BLOOD_BITE );
		return;
	}

	BaseClass::HandleAnimEvent( pEvent );
}
Пример #26
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CEnvBeam::Spawn( void )
{
	if ( !m_iszSpriteName )
	{
		SetThink( &CEnvBeam::SUB_Remove );
		return;
	}

	BaseClass::Spawn();

	m_noiseAmplitude = MIN(MAX_BEAM_NOISEAMPLITUDE, m_noiseAmplitude);

	// Check for tapering
	if ( HasSpawnFlags( SF_BEAM_TAPEROUT ) )
	{
		SetWidth( m_boltWidth );
		SetEndWidth( 0 );
	}
	else
	{
		SetWidth( m_boltWidth );
		SetEndWidth( GetWidth() );	// Note: EndWidth is not scaled
	}

	// if a non-targetentity endpoint was specified, transform it into local relative space
	// so it can move along with the base
	if (!m_vEndPointWorld.IsZero())
	{
		WorldToEntitySpace( m_vEndPointWorld, &m_vEndPointRelative );
	}
	else
	{
		m_vEndPointRelative.Zero();
	}


	if ( ServerSide() )
	{
		SetThink( &CEnvBeam::UpdateThink );
		SetNextThink( gpGlobals->curtime );
		SetFireTime( gpGlobals->curtime );

		if ( GetEntityName() != NULL_STRING )
		{
			if ( !(m_spawnflags & SF_BEAM_STARTON) )
			{
				AddEffects( EF_NODRAW );
				m_active = 0;
				SetNextThink( TICK_NEVER_THINK );
			}
			else
			{
				m_active = 1;
			}
		}
	}
	else
	{
		m_active = 0;
		if ( !GetEntityName() || FBitSet(m_spawnflags, SF_BEAM_STARTON) )
		{
			SetThink( &CEnvBeam::StrikeThink );
			SetNextThink( gpGlobals->curtime + 1.0f );
		}
	}

}
Пример #27
0
//=========================================================
// Selecciona un objeto al azar.
//=========================================================
const char *CLoot::SelectRandomItem()
{
	int pRandom			= random->RandomInt(1, 15);
	const char *pResult = "";

	if ( pRandom == 1 && HasSpawnFlags(SF_SPAWN_PISTOL) )
		pResult = "item_ammo_pistol";

	if ( pRandom == 2 && HasSpawnFlags(SF_SPAWN_AR2) )
		pResult = "item_ammo_ar2";

	if ( pRandom == 3 && HasSpawnFlags(SF_SPAWN_SMG1) )
		pResult = "item_ammo_smg1";

	if ( pRandom == 4 && HasSpawnFlags(SF_SPAWN_SHOTGUN) )
		pResult = "item_box_buckshot";

	if ( pRandom == 5 && HasSpawnFlags(SF_SPAWN_357) )
		pResult = "item_ammo_357";

	//if ( pRandom == 6 && HasSpawnFlags(SF_SPAWN_ALYXGUN) )
		//pResult = "weapon_alyxgun";

	if ( pRandom == 7 && HasSpawnFlags(SF_SPAWN_CROSSBOW) )
		pResult = "item_ammo_crossbow";

	if ( pRandom == 8 && HasSpawnFlags(SF_SPAWN_FRAG) )
		pResult = "weapon_frag";

	if ( pRandom == 9 && HasSpawnFlags(SF_SPAWN_HEALTHKIT) )
	{
		if ( random->RandomInt(1, 5) == 2 )
			pResult = "item_healthvial";
		else
			pResult = "item_healthkit";
	}

	if ( pRandom == 10 && HasSpawnFlags(SF_SPAWN_BATTERY) )
		pResult = "item_battery";

	if ( pRandom == 11 && HasSpawnFlags(SF_SPAWN_BLOOD) )
		pResult = "item_bloodkit";

	if ( pRandom == 12 && HasSpawnFlags(SF_SPAWN_BANDAGE) )
		pResult = "item_bandage";

	if ( pRandom == 13 && HasSpawnFlags(SF_SPAWN_SODA) )
		pResult = "item_soda";

	if ( pRandom == 14 && HasSpawnFlags(SF_SPAWN_FOOD) )
		pResult = "item_food";

	// Hacemos otra pasada a la suerte.
	if ( pResult == "" )
		return SelectRandomItem();

	// Es munición.
	if ( Q_stristr(pResult, "ammo") && pResult != "item_ammo_crossbow" )
	{
		// ¡Suerte! Toca una caja grande de munición.
		if ( random->RandomInt(1, 5) > 3 )
			pResult = CFmtStr("%s_large", pResult);
	}

	return pResult;
}
Пример #28
0
//---------------------------------------------------------
//---------------------------------------------------------
void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBaseEntity *pActivator, CBaseEntity *pCaller )
{
 	if( iReverting != NOT_REVERTING && m_iPreviousDisposition == -1 )
	{
		// Trying to revert without having ever set the relationships!
		DevMsg( 2, "ai_relationship cannot revert changes before they are applied!\n");
		return;
	}

	const int MAX_HANDLED = 512;
	CUtlVectorFixed<CBaseCombatCharacter *, MAX_HANDLED> subjectList;
	CUtlVectorFixed<CBaseCombatCharacter *, MAX_HANDLED> targetList;

	// Add any special subjects we found
	CBaseEntity *pSpecialSubject = FindEntityForProceduralName( m_iszSubject, pActivator, pCaller );
	if ( pSpecialSubject && pSpecialSubject->MyCombatCharacterPointer() )
	{
		subjectList.AddToTail( pSpecialSubject->MyCombatCharacterPointer() );
	}

	// Add any special targets we found
	CBaseEntity *pSpecialTarget = FindEntityForProceduralName( m_target, pActivator, pCaller );
	if ( pSpecialTarget && pSpecialTarget->MyCombatCharacterPointer() )
	{
		targetList.AddToTail( pSpecialTarget->MyCombatCharacterPointer() );
	}

	// -------------------------------
	// Search for targets and subjects
	// -------------------------------

	float radiusSq = Square( m_flRadius );
	
	// Search players first
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED )
		{
			DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() );
			break;
		}

		CBasePlayer	*pPlayer = UTIL_PlayerByIndex( i );
		if ( pPlayer )
		{
			if( IsASubject( pPlayer ) )
			{
				if ( m_flRadius == 0.0 || GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() ) <= radiusSq )
					subjectList.AddToTail( pPlayer );
			}
			else if( IsATarget( pPlayer ) )
			{
				targetList.AddToTail( pPlayer );
			}
		}
	}

	// Search NPCs
	for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )
	{
		if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED )
		{
			DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() );
			break;
		}

		CAI_BaseNPC *pNPC = (g_AI_Manager.AccessAIs())[i];
		if ( pNPC )
		{
			if( IsASubject( pNPC ) )
			{
				if ( m_flRadius == 0.0 || GetAbsOrigin().DistToSqr( pNPC->GetAbsOrigin() ) <= radiusSq )
					subjectList.AddToTail( pNPC );
			}
			else if( IsATarget( pNPC ) )
			{
				targetList.AddToTail( pNPC );
			}
		}
	}

	// If either list is still empty, we have a problem.
	if( subjectList.Count() == 0 )
	{
		DevMsg( 2, "ai_relationship '%s' finds no subject(s) called: %s\n", GetDebugName(), STRING( m_iszSubject ) );
		return;
	}
	else if ( targetList.Count() == 0 )
	{
		DevMsg( 2, "ai_relationship '%s' finds no target(s) called: %s\n", GetDebugName(), STRING( m_target ) );
		return;
	}

	// Ok, lists are populated. Apply all relationships.
	for ( int i = 0 ; i < subjectList.Count(); i++ )
	{
		CBaseCombatCharacter *pSubject = subjectList[ i ];

		for ( int j = 0 ; j < targetList.Count(); j++ )
		{
			CBaseCombatCharacter *pTarget = targetList[ j ];

			if ( m_iPreviousDisposition == -1 && iReverting == NOT_REVERTING )
			{
				// Set previous disposition.
				m_iPreviousDisposition = pSubject->IRelationType( pTarget );
				m_iPreviousRank = pSubject->IRelationPriority( pTarget );
			}

			if ( iReverting == REVERTING_TO_PREV )
			{
				pSubject->AddEntityRelationship( pTarget, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank );

				if( m_bReciprocal )
				{
					pTarget->AddEntityRelationship( pSubject, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank );
				}
			}
			else if ( iReverting == REVERTING_TO_DEFAULT )
			{
				pSubject->RemoveEntityRelationship( pTarget );

				if( m_bReciprocal )
				{
					pTarget->RemoveEntityRelationship( pSubject );
				}
			}
			else if( pSubject->IRelationType(pTarget) != disposition || 
				     pSubject->IRelationPriority(pTarget) != m_iRank || 
					 HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_SUBJECT ) ||
					 HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_TARGET ) )
			{
				// Apply the relationship to the subject
				pSubject->AddEntityRelationship( pTarget, (Disposition_t)disposition, m_iRank );

				// Make the subject aware of the target
				if ( HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_SUBJECT ) )
				{
					DiscloseNPCLocation( pSubject, pTarget );
				}

				// Make the target aware of the subject
				if ( HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_TARGET ) )
				{
					DiscloseNPCLocation( pTarget, pSubject );
				}

				// This relationship is applied to target and subject alike
				if ( m_bReciprocal )
				{
					// Apply the relationship to the target
					pTarget->AddEntityRelationship( pSubject, (Disposition_t)disposition, m_iRank );
				}
			}
		}
	}
}
Пример #29
0
void CWeaponHL2MPBase::FallInit( void )
{
#ifndef CLIENT_DLL
    SetModel( GetWorldModel() );
    VPhysicsDestroyObject();

    if ( HasSpawnFlags( SF_NORESPAWN ) == false )
    {
        SetMoveType( MOVETYPE_NONE );
        SetSolid( SOLID_BBOX );
        AddSolidFlags( FSOLID_TRIGGER );

        UTIL_DropToFloor( this, MASK_SOLID );
    }
    else
    {
        if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) )
        {
            SetMoveType( MOVETYPE_NONE );
            SetSolid( SOLID_BBOX );
            AddSolidFlags( FSOLID_TRIGGER );
        }
        else
        {
#if !defined( CLIENT_DLL )
            // Constrained start?
            if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) )
            {
                //Constrain the weapon in place
                IPhysicsObject *pReferenceObject, *pAttachedObject;

                pReferenceObject = g_PhysWorldObject;
                pAttachedObject = VPhysicsGetObject();

                if ( pReferenceObject && pAttachedObject )
                {
                    constraint_fixedparams_t fixed;
                    fixed.Defaults();
                    fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );

                    fixed.constraint.forceLimit	= lbs2kg( 10000 );
                    fixed.constraint.torqueLimit = lbs2kg( 10000 );

                    IPhysicsConstraint *pConstraint = GetConstraint();

                    pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );

                    pConstraint->SetGameData( (void *) this );
                }
            }
#endif //CLIENT_DLL
        }
    }

    SetPickupTouch();

    SetThink( &CBaseCombatWeapon::FallThink );

    SetNextThink( gpGlobals->curtime + 0.1f );

#endif
}
Пример #30
0
//-----------------------------------------------------------------------------
// Purpose: Checks to see if it's time to change controllers
//-----------------------------------------------------------------------------
void CControlZone::ReevaluateControllingTeam( void )
{
	// Count the number of players in each team
	int i;
	memset( m_iPlayersInZone, 0, sizeof( m_iPlayersInZone ) );
	for ( i = 0; i < m_ZonePlayerList.Size(); i++ )
	{
		if ( m_ZonePlayerList[i] != NULL && (m_ZonePlayerList[i]->GetTeamNumber() > 0) )
		{
			m_iPlayersInZone[ m_ZonePlayerList[i]->GetTeamNumber() ] += 1;
		}
	}

	// Abort immediately if we're not using touches to changes teams
	if ( HasSpawnFlags( CZF_DONT_USE_TOUCHES ) )
		return;

	// if we're locked in place, no changes can occur to controlling team except through an explicit map ResetTeam
	if ( m_iLocked )
		return;

	bool foundAnyTeam = false;
	int teamFound = 0;

	// check to see if any teams have no players
	for ( i = 0; i < GetNumberOfTeams(); i++ )
	{
		if ( m_iPlayersInZone[i] )
		{
			if ( foundAnyTeam )
			{
				// we've already found a team, so it's being contested;
				teamFound = ZONE_CONTESTED;
				break;
			}

			foundAnyTeam = true;
			teamFound = i;			
		}
	}

	// no one in the area!
	if ( teamFound == 0 )
	{
		// just leave it as it is, let it continue to change team
		// exception: if the zone state is contested, and there aren't any players in the zone,
		// just return to the team who used to own the zone.
		if ( GetTeamNumber() == ZONE_CONTESTED )
		{
			ChangeTeam(m_iDefendingTeam);
			SetControllingTeam( this, m_iDefendingTeam );
		}

		return;
	}

	// if it's the same controlling team, don't worry about it
	if ( teamFound == GetTeamNumber() )
	{
		// the right team is in control, don't even think of switching
		m_iTryingToChangeToTeam = 0;
		SetNextThink( TICK_NEVER_THINK );
		return;
	}

	// Find out if the zone isn't owned by anyone at all (hasn't been touched since the map started, and it started un-owned)
	bool bHasBeenOwned = true;
	if ( m_iDefendingTeam == 0 && GetTeamNumber() == 0 ) 
		bHasBeenOwned = false;

	// if it's not contested, always go to contested mode 
	if ( GetTeamNumber() != ZONE_CONTESTED && teamFound != GetTeamNumber() )
	{
		// Unowned zones are captured immediately (no contesting stage)
		if ( bHasBeenOwned )
			teamFound = ZONE_CONTESTED;
	}

	// if it's the team we're trying to change to, don't worry about it
	if ( teamFound == m_iTryingToChangeToTeam )
		return;

	// set up the time to change to the new team soon
	m_iTryingToChangeToTeam = teamFound;

	// changing from contested->uncontested and visa-versa have different delays
	if ( m_iTryingToChangeToTeam != ZONE_CONTESTED )
	{
		if ( !bHasBeenOwned )
		{
			DevMsg( 1, "trigger_controlzone: (%s) changing team to %d NOW\n", GetDebugName(), m_iTryingToChangeToTeam );
			SetNextThink( gpGlobals->curtime + 0.1f );
		}
		else
		{
			DevMsg( 1, "trigger_controlzone: (%s) changing team to %d in %.2f seconds\n", GetDebugName(), m_iTryingToChangeToTeam, m_flTimeTillCaptured );
			SetNextThink( gpGlobals->curtime + m_flTimeTillCaptured );
		}
	}
	else
	{
		DevMsg( 1, "trigger_controlzone: (%s) changing to contested in %f seconds\n", GetDebugName(), m_flTimeTillContested );
		SetNextThink( gpGlobals->curtime + m_flTimeTillContested );
	}
}