// 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 ); }