Beispiel #1
0
// TEMPLATE    -> k_template string
//
int P_Template()
{
    int nRet;
    PSTATEDESC pDesc;
    ObjectType object;

    pDesc = s_pContext->CreateStatement(State_Template);
    if (!pDesc) {
        ErrorReport(Lube_E_OutOfMemory);
        return Ret_AbortOnError;
    }
    if (_GetToken() != Token_string) {
        ErrorReport(Lube_E_ExpectSymbol, "template name");
        return Ret_AbortOnError;
    }

    nRet = FindTemplate(s_pContext->m_pLube, g_szCurrentToken);
    if (nRet < 0) {
        nRet = DoCompiling(g_szCurrentToken);
    }
    if (nRet >= 0) {
        pDesc->dwExtra = nRet;
        object = s_pContext->m_pLube->ppTemplates[nRet]->tRoot.object;
        if (Object_Class == object) {
            if (s_pContext->m_nClass > 0) {
                pDesc->object = Object_Class;
            }
            else {
                ErrorReport(Lube_E_NoValidObject, "class");
            }
        }
        else if (Object_Interface == object) {
            if (s_pContext->m_nInterface > 0) {
                pDesc->object = Object_Interface;
            }
            else {
                ErrorReport(Lube_E_NoValidObject, "interface");
            }
        }
    }

    s_pContext->LeaveStatement();
    return Ret_Continue;
}
//-----------------------------------------------------------------------------
// Purpose: Spawns the entities, checking for space if flagged to do so.
//-----------------------------------------------------------------------------
void CEnvEntityMaker::InputForceSpawn( inputdata_t &inputdata )
{
	CPointTemplate *pTemplate = FindTemplate();
	if (!pTemplate)
		return;

	if ( HasSpawnFlags( SF_ENTMAKER_CHECK_FOR_SPACE ) && !HasRoomToSpawn() )
	{
		m_pOutputOnFailedSpawn.FireOutput( this, this );
		return;
	}

	if ( HasSpawnFlags( SF_ENTMAKER_CHECK_PLAYER_LOOKING ) && IsPlayerLooking() )
	{
		m_pOutputOnFailedSpawn.FireOutput( this, this );
		return;
	}

	SpawnEntity();
}
//-----------------------------------------------------------------------------
// Purpose: Spawn an instance of the entity
//-----------------------------------------------------------------------------
void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternateAngles )
{
	CPointTemplate *pTemplate = FindTemplate();
	if (!pTemplate)
		return;

	// Spawn our template
	Vector vecSpawnOrigin = GetAbsOrigin();
	QAngle vecSpawnAngles = GetAbsAngles();

	if( vecAlternateOrigin != vec3_invalid )
	{
		// We have a valid alternate origin and angles. Use those instead
		// of spawning the items at my own origin and angles.
		vecSpawnOrigin = vecAlternateOrigin;
		vecSpawnAngles = vecAlternateAngles;
	}

	CUtlVector<CBaseEntity*> hNewEntities;
	if ( !pTemplate->CreateInstance( vecSpawnOrigin, vecSpawnAngles, &hNewEntities, this ) )
		return;
	
	//Adrian: oops we couldn't spawn the entity (or entities) for some reason!
	if ( hNewEntities.Count() == 0 )
		 return;
	
	m_hCurrentInstance = hNewEntities[0];

	// Assume it'll block us
	m_hCurrentBlocker = m_hCurrentInstance;
	m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin();

	// Store off the mins & maxs the first time we spawn
	if ( m_vecEntityMins == vec3_origin )
	{
		m_hCurrentInstance->CollisionProp()->WorldSpaceAABB( &m_vecEntityMins, &m_vecEntityMaxs );
		m_vecEntityMins -= m_hCurrentInstance->GetAbsOrigin();
		m_vecEntityMaxs -= m_hCurrentInstance->GetAbsOrigin();
	}

	// Fire our output
	m_pOutputOnSpawned.FireOutput( this, this );

	// Start thinking
	if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN )
	{
		SetThink( &CEnvEntityMaker::CheckSpawnThink );
		SetNextThink( gpGlobals->curtime + 0.5f );
	}

	// If we have a specified post spawn speed, apply it to all spawned entities
	if ( m_flPostSpawnSpeed )
	{
		for ( int i = 0; i < hNewEntities.Count(); i++ )
		{
			CBaseEntity *pEntity = hNewEntities[i];
			if ( pEntity->GetMoveType() == MOVETYPE_NONE )
				continue;

			// Calculate a velocity for this entity
			Vector vForward,vRight,vUp;
			QAngle angSpawnDir( m_angPostSpawnDirection );
			if ( m_bPostSpawnUseAngles )
			{
				if ( GetParent() )
				{
					angSpawnDir += GetParent()->GetAbsAngles();
				}
				else
				{
					angSpawnDir += GetAbsAngles();
				}
			}
			AngleVectors( angSpawnDir, &vForward, &vRight, &vUp );
			Vector vecShootDir = vForward;
			vecShootDir += vRight * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
			vecShootDir += vForward * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
			vecShootDir += vUp * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance;
			VectorNormalize( vecShootDir );
			vecShootDir *= m_flPostSpawnSpeed;

			// Apply it to the entity
			IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject();
			if ( pPhysicsObject )
			{
				pPhysicsObject->AddVelocity(&vecShootDir, NULL);
			}
			else
			{
				pEntity->SetAbsVelocity( vecShootDir );
			}
		}
	}

	pTemplate->CreationComplete( hNewEntities );
}