void UTIL_EmitSoundSuit(edict_t *entity, const char *sample) { float fvol; int pitch = PITCH_NORM; fvol = suitvolume.GetFloat(); if (random->RandomInt(0,1)) pitch = random->RandomInt(0,6) + 98; // If friendlies are talking, reduce the volume of the suit if ( !g_AIFriendliesTalkSemaphore.IsAvailable( GetContainingEntity( entity ) ) ) { fvol *= 0.3; } if (fvol > 0.05) { CPASAttenuationFilter filter( GetContainingEntity( entity ) ); filter.MakeReliable(); EmitSound_t ep; ep.m_nChannel = CHAN_STATIC; ep.m_pSoundName = sample; ep.m_flVolume = fvol; ep.m_SoundLevel = SNDLVL_NORM; ep.m_nPitch = pitch; CBaseEntity::EmitSound( filter, ENTINDEX(entity), ep ); } }
int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, float volume, soundlevel_t soundlevel, int flags, int pitch) { char name[64]; int ipick; int isentenceg; if (!fSentencesInit) return -1; name[0] = 0; isentenceg = engine->SentenceGroupIndexFromName(szgroupname); if (isentenceg < 0) { Warning( "No such sentence group %s\n", szgroupname ); return -1; } ipick = engine->SentenceGroupPick(isentenceg, name, sizeof( name )); if (ipick >= 0 && name[0]) { int sentenceIndex = SENTENCEG_Lookup( name ); CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); CBaseEntity::EmitSentenceByIndex( filter, ENTINDEX(entity), CHAN_VOICE, sentenceIndex, volume, soundlevel, flags, pitch ); return sentenceIndex; } return -1; }
//----------------------------------------------------------------------------- // Purpose: // Input : index - // *pEvent - //----------------------------------------------------------------------------- void CGrubNugget::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) { int damageType; float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0f, true, damageType ); if ( damage > 5.0f ) { CBaseEntity *pHitEntity = pEvent->pEntities[!index]; if ( pHitEntity == NULL ) { // hit world pHitEntity = GetContainingEntity( INDEXENT(0) ); } Vector damagePos; pEvent->pInternalData->GetContactPoint( damagePos ); Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass(); if ( damageForce == vec3_origin ) { // This can happen if this entity is motion disabled, and can't move. // Use the velocity of the entity that hit us instead. damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass(); } // FIXME: this doesn't pass in who is responsible if some other entity "caused" this collision PhysCallbackDamage( this, CTakeDamageInfo( pHitEntity, pHitEntity, damageForce, damagePos, damage, damageType ), *pEvent, index ); } BaseClass::VPhysicsCollision( index, pEvent ); }
int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, float volume, soundlevel_t soundlevel, int flags, int pitch, int ipick, int freset) { char name[64]; int ipicknext; int isentenceg; if (!fSentencesInit) return -1; name[0] = 0; isentenceg = engine->SentenceGroupIndexFromName(szgroupname); if (isentenceg < 0) return -1; ipicknext = engine->SentenceGroupPickSequential(isentenceg, name, sizeof( name ), ipick, freset); if (ipicknext >= 0 && name[0]) { int sentenceIndex = SENTENCEG_Lookup( name ); CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); CBaseEntity::EmitSentenceByIndex( filter, ENTINDEX(entity), CHAN_VOICE, sentenceIndex, volume, soundlevel, flags, pitch ); return sentenceIndex; } return -1; }
//----------------------------------------------------------------------------- // Plays a sentence by sentence index //----------------------------------------------------------------------------- void SENTENCEG_PlaySentenceIndex( edict_t *entity, int iSentenceIndex, float volume, soundlevel_t soundlevel, int flags, int pitch ) { if ( iSentenceIndex >= 0 ) { CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); CBaseEntity::EmitSentenceByIndex( filter, ENTINDEX(entity), CHAN_VOICE, iSentenceIndex, volume, soundlevel, flags, pitch ); } }
//----------------------------------------------------------------------------- // Purpose: Given a player and optional name returns the entity of that // classname that the player is nearest facing // // Input : // Output : //----------------------------------------------------------------------------- CBaseEntity* FindEntity( edict_t *pEdict, char *classname) { // If no name was given set bits based on the picked if (FStrEq(classname,"")) return (FindPickerEntityClass( static_cast<CBasePlayer*>(GetContainingEntity(pEdict)), classname )); return NULL; }
//----------------------------------------------------------------------------- // Purpose: Called when the player falls onto a surface fast enough to take // damage, according to the rules in CGameMovement::CheckFalling. // Output : Returns true if the player survived the fall, false if they died. //----------------------------------------------------------------------------- bool CMoveHelperServer::PlayerFallingDamage( void ) { float flFallDamage = g_pGameRules->FlPlayerFallDamage( m_pHostPlayer ); if ( flFallDamage > 0 ) { m_pHostPlayer->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), flFallDamage, DMG_FALL ) ); StartSound( m_pHostPlayer->GetAbsOrigin(), "Player.FallDamage" ); //============================================================================= // HPE_BEGIN: // [dwenger] Needed for fun-fact implementation //============================================================================= #ifdef CSTRIKE_DLL // Increment the stat for fall damage CCSPlayer* pPlayer = ToCSPlayer(m_pHostPlayer); if ( pPlayer ) { CCS_GameStats.IncrementStat( pPlayer, CSSTAT_FALL_DAMAGE, (int)flFallDamage ); } #endif //============================================================================= // HPE_END //============================================================================= } if ( m_pHostPlayer->m_iHealth <= 0 ) { if ( g_pGameRules->FlPlayerFallDeathDoesScreenFade( m_pHostPlayer ) ) { color32 black = {0, 0, 0, 255}; UTIL_ScreenFade( m_pHostPlayer, black, 0, 9999, FFADE_OUT | FFADE_STAYOUT ); } return(false); } return(true); }
//----------------------------------------------------------------------------- // After we built the touch list, deal with all the impacts... //----------------------------------------------------------------------------- void CMoveHelperServer::ProcessImpacts( void ) { Assert( m_pHostPlayer ); // Relink in order to build absorigin and absmin/max to reflect any changes // from prediction. Relink will early out on SOLID_NOT engine->RelinkEntity( m_pHostPlayer->pev, true ); // Don't bother if the player ain't solid if ( m_pHostPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) { return; } // Save off the velocity, cause we need to temporarily reset it Vector vel = m_pHostPlayer->GetAbsVelocity(); // Touch other objects that were intersected during the movement. for (int i = 0 ; i < m_TouchList.Size(); i++) { CBaseHandle entindex = m_TouchList[i].trace.m_pEnt->GetRefEHandle(); // We should have culled negative indices by now Assert( entindex.IsValid() ); edict_t* ent = GetEdict( entindex ); if (!ent) continue; // Run the impact function as if we had run it during movement. CBaseEntity *entity = GetContainingEntity( ent ); if ( !entity ) continue; Assert( entity != m_pHostPlayer ); // Don't ever collide with self!!!! if ( entity == m_pHostPlayer ) continue; // Reconstruct trace results. m_TouchList[i].trace.m_pEnt = CBaseEntity::Instance( ent ); // Use the velocity we had when we collided, so boxes will move, etc. m_pHostPlayer->SetAbsVelocity( m_TouchList[i].deltavelocity ); entity->PhysicsImpact( m_pHostPlayer, m_TouchList[i].trace ); } // Restore the velocity m_pHostPlayer->SetAbsVelocity( vel ); // So no stuff is ever left over, sigh... ResetTouchList(); }
//----------------------------------------------------------------------------- // Purpose: Called when the player falls onto a surface fast enough to take // damage, according to the rules in CGameMovement::CheckFalling. // Output : Returns true if the player survived the fall, false if they died. //----------------------------------------------------------------------------- bool CMoveHelperServer::PlayerFallingDamage( void ) { float flFallDamage = g_pGameRules->FlPlayerFallDamage( m_pHostPlayer ); if ( flFallDamage > 0 ) { StartSound( m_pHostPlayer->GetAbsOrigin(), "Player.FallDamage" ); m_pHostPlayer->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), flFallDamage, DMG_FALL ) ); } if ( m_pHostPlayer->m_iHealth <= 0 ) { if ( g_pGameRules->FlPlayerFallDeathDoesScreenFade( m_pHostPlayer ) ) { color32 black = {0, 0, 0, 255}; UTIL_ScreenFade( m_pHostPlayer, black, 0, 9999, FFADE_OUT | FFADE_STAYOUT ); } return(false); } return(true); }
void FreeContainingEntity( edict_t *ed ) { if ( ed ) { CBaseEntity *ent = GetContainingEntity( ed ); if ( ent ) { ed->SetEdict( NULL, false ); CBaseEntity::PhysicsRemoveTouchedList( ent ); CBaseEntity::PhysicsRemoveGroundList( ent ); UTIL_RemoveImmediate( ent ); } } }
//========================================================= // Devuelve al jugador con la Index especificada. //========================================================= CIN_Player *UTIL_InPlayerByIndex(int playerIndex) { CIN_Player *pPlayer = NULL; if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients ) { edict_t *pPlayerEdict = INDEXENT(playerIndex); if ( pPlayerEdict && !pPlayerEdict->IsFree() ) pPlayer = (CIN_Player*)GetContainingEntity(pPlayerEdict); } return pPlayer; }
//----------------------------------------------------------------------------- // Purpose: Create a missile //----------------------------------------------------------------------------- CGrenadeRocket *CGrenadeRocket::Create( const Vector &vecOrigin, const Vector &vecForward, edict_t *pentOwner = NULL, CBaseEntity *pRealOwner = NULL ) { CGrenadeRocket *pRocket = (CGrenadeRocket *)CreateEntityByName("grenade_rocket" ); UTIL_SetOrigin( pRocket, vecOrigin ); QAngle angles; VectorAngles( vecForward, angles ); pRocket->SetLocalAngles( angles ); pRocket->Spawn(); pRocket->SetOwnerEntity( Instance( pentOwner ) ); pRocket->m_pRealOwner = pRealOwner; if (pentOwner) { CBaseEntity *pOwnerEnt = GetContainingEntity( pentOwner ); pRocket->ChangeTeam( pOwnerEnt->GetTeamNumber() ); } return pRocket; }
int UTIL_EmitGroupnameSuit(edict_t *entity, const char *groupname) { float fvol; int pitch = PITCH_NORM; int sentenceIndex = -1; fvol = suitvolume.GetFloat(); if (random->RandomInt(0,1)) pitch = random->RandomInt(0,6) + 98; // If friendlies are talking, reduce the volume of the suit if ( !g_AIFriendliesTalkSemaphore.IsAvailable( GetContainingEntity( entity ) ) ) { fvol *= 0.3; } if (fvol > 0.05) sentenceIndex = SENTENCEG_PlayRndSz(entity, groupname, fvol, SNDLVL_NORM, 0, pitch); return sentenceIndex; }
int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, soundlevel_t soundlevel, int flags, int pitch) { char name[64]; int ipick; if (!fSentencesInit) return -1; name[0] = 0; ipick = engine->SentenceGroupPick( isentenceg, name, sizeof( name ) ); if (ipick > 0 && name) { int sentenceIndex = SENTENCEG_Lookup( name ); CPASAttenuationFilter filter( GetContainingEntity( entity ), soundlevel ); CBaseEntity::EmitSentenceByIndex( filter, ENTINDEX(entity), CHAN_VOICE, sentenceIndex, volume, soundlevel, flags, pitch ); return sentenceIndex; } return -1; }
void CFuncTank::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); // Get a position to aim for if (m_pController) { // Tanks attempt to mirror the player's angles angles = m_pController->EyeAngles(); SetNextThink( gpGlobals->curtime + 0.05 ); } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; if (m_spawnflags & SF_TANK_AIM_AT_POS) { worldTargetPosition = m_vTargetPosition; } else { CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { if ( m_targetEntityName != NULL_STRING ) // New HL2 behavior { m_hTarget = FindTarget( m_targetEntityName, NULL ); } else // HL1 style { m_hTarget = ToBasePlayer( GetContainingEntity( UTIL_FindClientInPVS( edict() ) ) ); } if ( m_hTarget != NULL ) { SetNextThink( gpGlobals->curtime ); // Think again immediately } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 secs } if ( m_fireLast !=0 ) { m_OnLoseTarget.FireOutput(this, this); m_fireLast = 0; } } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); } float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) { m_fireLast = 0; return; } UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if (m_spawnflags & SF_TANK_AIM_AT_POS) { updateTime = TRUE; m_sightOrigin = m_vTargetPosition; } else { lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); } // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Limit against range in y // MDB - don't check pitch! If two func_tanks are meant to align, // and one can pitch and the other cannot, this can lead to them getting // different values for angles.y. Nothing is lost by not updating yaw // because the target is not in pitch range. bool bOutsideYawRange = ( fabs( offsetY ) > m_yawRange + m_yawTolerance ); bool bOutsidePitchRange = ( fabs( offsetX ) > m_pitchRange + m_pitchTolerance ); Vector vecToTarget = m_sightOrigin - GetLocalOrigin(); // if target is outside yaw range if ( bOutsideYawRange ) { if ( angles.y > m_yawCenter + m_yawRange ) { angles.y = m_yawCenter + m_yawRange; } else if ( angles.y < (m_yawCenter - m_yawRange) ) { angles.y = (m_yawCenter - m_yawRange); } } if ( bOutsidePitchRange || bOutsideYawRange || ( vecToTarget.Length() < ( barrelEnd - GetAbsOrigin() ).Length() ) ) { // Don't update if you saw the player, but out of range updateTime = false; } if ( updateTime ) { m_lastSightTime = gpGlobals->curtime; m_persist2burst = 0; } // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Limit against range in x angles.x = clamp( angles.x, m_pitchCenter - m_pitchRange, m_pitchCenter + m_pitchRange ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); if ( m_pController ) return; if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (m_spawnflags & SF_TANK_LINEOFSIGHT) ) ) { bool fire = FALSE; Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); if ( m_spawnflags & SF_TANK_LINEOFSIGHT ) { float length = (m_maxRange > 0) ? m_maxRange : MAX_TRACE_LENGTH; UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( tr.m_pEnt == pTarget ) fire = TRUE; } else fire = TRUE; if ( fire ) { if (m_fireLast == 0) { m_OnAquireTarget.FireOutput(this, this); } FiringSequence( barrelEnd, forward, this ); } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } }
CBaseEntity* CHL2MP_Player::EntSelectSpawnPoint( void ) { CBaseEntity *pSpot = NULL; CBaseEntity *pLastSpawnPoint = g_pLastSpawn; edict_t *player = edict(); const char *pSpawnpointName = "info_player_deathmatch"; if ( HL2MPRules()->IsTeamplay() == true ) { if ( GetTeamNumber() == TEAM_COMBINE ) { pSpawnpointName = "info_player_combine"; pLastSpawnPoint = g_pLastCombineSpawn; } else if ( GetTeamNumber() == TEAM_REBELS ) { pSpawnpointName = "info_player_rebel"; pLastSpawnPoint = g_pLastRebelSpawn; } if ( gEntList.FindEntityByClassname( NULL, pSpawnpointName ) == NULL ) { pSpawnpointName = "info_player_deathmatch"; pLastSpawnPoint = g_pLastSpawn; } } pSpot = pLastSpawnPoint; // Randomize the start spot for ( int i = random->RandomInt(1,5); i > 0; i-- ) pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); if ( !pSpot ) // skip over the null point pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); CBaseEntity *pFirstSpot = pSpot; do { if ( pSpot ) { // check if pSpot is valid if ( g_pGameRules->IsSpawnPointValid( pSpot, this ) ) { if ( pSpot->GetLocalOrigin() == vec3_origin ) { pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); continue; } // if so, go to pSpot goto ReturnSpot; } } // increment pSpot pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); } while ( pSpot != pFirstSpot ); // loop if we're not back to the start // we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there if ( pSpot ) { CBaseEntity *ent = NULL; for ( CEntitySphereQuery sphere( pSpot->GetAbsOrigin(), 128 ); (ent = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() ) { // if ent is a client, kill em (unless they are ourselves) if ( ent->IsPlayer() && !(ent->edict() == player) ) ent->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), 300, DMG_GENERIC ) ); } goto ReturnSpot; } if ( !pSpot ) { pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start" ); if ( pSpot ) goto ReturnSpot; } ReturnSpot: if ( HL2MPRules()->IsTeamplay() == true ) { if ( GetTeamNumber() == TEAM_COMBINE ) { g_pLastCombineSpawn = pSpot; } else if ( GetTeamNumber() == TEAM_REBELS ) { g_pLastRebelSpawn = pSpot; } } g_pLastSpawn = pSpot; m_flSlamProtectTime = gpGlobals->curtime + 0.5; return pSpot; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CRagdollProp::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) { BaseClass::VPhysicsCollision( index, pEvent ); CBaseEntity *pHitEntity = pEvent->pEntities[!index]; if ( pHitEntity == this ) return; // Don't take physics damage from whoever's holding him with the physcannon. if ( VPhysicsGetObject() && (VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) ) { if ( pHitEntity && (pHitEntity == HasPhysicsAttacker( FLT_MAX )) ) return; } // Don't bother taking damage from the physics attacker if ( pHitEntity && HasPhysicsAttacker( 0.5f ) == pHitEntity ) return; if( m_bFirstCollisionAfterLaunch ) { HandleFirstCollisionInteractions( index, pEvent ); } if ( m_takedamage != DAMAGE_NO ) { int damageType = 0; float damage = CalculateDefaultPhysicsDamage( index, pEvent, 1.0f, true, damageType ); if ( damage > 0 ) { // Take extra damage after we're punted by the physcannon if ( m_bFirstCollisionAfterLaunch ) { damage *= 10; } CBaseEntity *pHitEntity = pEvent->pEntities[!index]; if ( !pHitEntity ) { // hit world pHitEntity = GetContainingEntity( INDEXENT(0) ); } Vector damagePos; pEvent->pInternalData->GetContactPoint( damagePos ); Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass(); if ( damageForce == vec3_origin ) { // This can happen if this entity is motion disabled, and can't move. // Use the velocity of the entity that hit us instead. damageForce = pEvent->postVelocity[!index] * pEvent->pObjects[!index]->GetMass(); } // FIXME: this doesn't pass in who is responsible if some other entity "caused" this collision PhysCallbackDamage( this, CTakeDamageInfo( pHitEntity, pHitEntity, damageForce, damagePos, damage, damageType ), *pEvent, index ); } } if ( m_bFirstCollisionAfterLaunch ) { // Setup the think function to remove the flags SetThink( &CRagdollProp::ClearFlagsThink ); SetNextThink( gpGlobals->curtime ); } }
/* ============ ClientKill Player entered the suicide command ============ */ void ClientKill( edict_t *pEdict ) { CBasePlayer *pl = (CBasePlayer*) GetContainingEntity( pEdict ); pl->CommitSuicide(); }
CBaseEntity* CHL2MP_Player::EntSelectSpawnPoint( void ) { CBaseEntity *pSpot = NULL; CBaseEntity *pLastSpawnPoint = g_pLastSpawn; edict_t *player = edict(); const char *pSpawnpointName = "info_player_deathmatch"; pSpot = pLastSpawnPoint; // Randomize the start spot for ( int i = random->RandomInt(1,5); i > 0; i-- ) pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); if ( !pSpot ) // skip over the null point pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); CBaseEntity *pFirstSpot = pSpot; do { if ( pSpot ) { // check if pSpot is valid if ( g_pGameRules->IsSpawnPointValid( pSpot, this ) ) { if ( pSpot->GetLocalOrigin() == vec3_origin ) { pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); continue; } // if so, go to pSpot goto ReturnSpot; } } // increment pSpot pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName ); } while ( pSpot != pFirstSpot ); // loop if we're not back to the start // we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there if ( pSpot ) { CBaseEntity *ent = NULL; for ( CEntitySphereQuery sphere( pSpot->GetAbsOrigin(), 128 ); (ent = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() ) { // if ent is a client, kill em (unless they are ourselves) if ( ent->IsPlayer() && !(ent->edict() == player) ) ent->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), 300, DMG_GENERIC ) ); } goto ReturnSpot; } if ( !pSpot ) { char szMapName[256]; Q_strncpy(szMapName, STRING(gpGlobals->mapname), sizeof(szMapName)); Q_strlower(szMapName); //TDT - Information: Although we don't support official maps for gaming, they are useful for testing and these maps for whatever reason spawn you in the wrong location. As such this // code is here to force players to spawn at the beginning of the selected maps. Custom maps won't require this as they will have deathmatch/class based player starts. if (!Q_strnicmp(szMapName, "d1_canals_01a", 13) || !Q_strnicmp(szMapName, "d1_canals_03", 12) || !Q_strnicmp(szMapName, "d1_canals_13", 12) || !Q_strnicmp(szMapName, "d1_town_01", 10) || !Q_strnicmp(szMapName, "d1_town_01a", 11) || !Q_strnicmp(szMapName, "d1_town_02", 10) || !Q_strnicmp(szMapName, "d1_town_02a", 11) || !Q_strnicmp(szMapName, "d1_town_03", 10) || !Q_strnicmp(szMapName, "d1_town_04", 10) || !Q_strnicmp(szMapName, "d1_town_05", 10) || !Q_strnicmp(szMapName, "d2_coast_03", 11) || !Q_strnicmp(szMapName, "d2_coast_08", 11) || !Q_strnicmp(szMapName, "d2_coast_11", 11) || !Q_strnicmp(szMapName, "d2_prison_01", 12) || !Q_strnicmp(szMapName, "d2_prison_02", 12) || !Q_strnicmp(szMapName, "d2_prison_03", 12) || !Q_strnicmp(szMapName, "d2_prison_04", 12) || !Q_strnicmp(szMapName, "d2_prison_05", 12) || !Q_strnicmp(szMapName, "d2_prison_06", 12) || !Q_strnicmp(szMapName, "d2_prison_07", 12) || !Q_strnicmp(szMapName, "d2_prison_08", 12) || !Q_strnicmp(szMapName, "d3_c17_08", 9) || !Q_strnicmp(szMapName, "d3_citadel_01", 13) || !Q_strnicmp(szMapName, "d3_citadel_02", 13) || !Q_strnicmp(szMapName, "d3_citadel_03", 13) || !Q_strnicmp(szMapName, "d3_citadel_04", 13) || !Q_strnicmp(szMapName, "d3_citadel_05", 13) || !Q_strnicmp(szMapName, "d3_breen_01", 11) || !Q_strnicmp(szMapName, "ep1_c17_00", 10) || !Q_strnicmp(szMapName, "ep1_c17_00a", 11) || !Q_strnicmp(szMapName, "ep1_c17_02b", 11) || !Q_strnicmp(szMapName, "ep1_c17_05", 10) || !Q_strnicmp(szMapName, "ep2_outland_01a", 15) || !Q_strnicmp(szMapName, "ep2_outland_03", 14) || !Q_strnicmp(szMapName, "ep2_outland_08", 14) || !Q_strnicmp(szMapName, "ep2_outland_06", 14) ) { CBaseEntity *pEntity = NULL; CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); Vector vecOrigin = pPlayer->GetAbsOrigin(); pEntity = gEntList.FindEntityByClassnameNearest("item_suit", vecOrigin, 0); if (pEntity != NULL) { vecOrigin = pEntity->GetAbsOrigin(); pEntity = gEntList.FindEntityByClassnameNearest("info_player_start", vecOrigin, 0); pSpot = pEntity; pSpawnpointName = "info_player_start"; goto ReturnSpot; } else { pSpot = gEntList.FindEntityByClassname(pSpot, "info_player_start"); } } else if (!Q_strnicmp(szMapName, "d1_trainstation_05", 18)) { CBaseEntity *pEntity = NULL; CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); Vector vecOrigin = pPlayer->GetAbsOrigin(); pEntity = gEntList.FindEntityByClassnameNearest("npc_alyx", vecOrigin, 0); if (pEntity != NULL) { vecOrigin = pEntity->GetAbsOrigin(); pEntity = gEntList.FindEntityByClassnameNearest("info_player_start", vecOrigin, 0); pSpot = pEntity; pSpawnpointName = "info_player_start"; goto ReturnSpot; } else { pSpot = gEntList.FindEntityByClassname(pSpot, "info_player_start"); } } else { pSpot = gEntList.FindEntityByClassname(pSpot, "info_player_start"); } if ( pSpot ) goto ReturnSpot; } ReturnSpot: g_pLastSpawn = pSpot; m_flSlamProtectTime = gpGlobals->curtime + 0.5; return pSpot; }
void ClientKill( edict_t *pEdict, const Vector &vecForce, bool bExplode = false ) { CBasePlayer *pPlayer = static_cast<CBasePlayer*>( GetContainingEntity( pEdict ) ); pPlayer->CommitSuicide( vecForce, bExplode ); }
void CC_CollisionTest( const CCommand &args ) { if ( !physenv ) return; Msg( "Testing collision system\n" ); int i; CBaseEntity *pSpot = gEntList.FindEntityByClassname( NULL, "info_player_start"); Vector start = pSpot->GetAbsOrigin(); static Vector *targets = NULL; static bool first = true; static float test[2] = {1,1}; if ( first ) { targets = new Vector[NUM_COLLISION_TESTS]; float radius = 0; float theta = 0; float phi = 0; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { radius += NUM_COLLISION_TESTS * 123.123; radius = fabs(fmod(radius, 128)); theta += NUM_COLLISION_TESTS * 76.76; theta = fabs(fmod(theta, DEG2RAD(360))); phi += NUM_COLLISION_TESTS * 1997.99; phi = fabs(fmod(phi, DEG2RAD(180))); float st, ct, sp, cp; SinCos( theta, &st, &ct ); SinCos( phi, &sp, &cp ); targets[i].x = radius * ct * sp; targets[i].y = radius * st * sp; targets[i].z = radius * cp; // make the trace 1024 units long Vector dir = targets[i] - start; VectorNormalize(dir); targets[i] = start + dir * 1024; } first = false; } //Vector results[NUM_COLLISION_TESTS]; int testType = 0; if ( args.ArgC() >= 2 ) { testType = atoi( args[1] ); } float duration = 0; Vector size[2]; size[0].Init(0,0,0); size[1].Init(16,16,16); unsigned int dots = 0; for ( int j = 0; j < 2; j++ ) { float startTime = engine->Time(); if ( testType == 1 ) { const CPhysCollide *pCollide = g_PhysWorldObject->GetCollide(); trace_t tr; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { physcollision->TraceBox( start, targets[i], -size[j], size[j], pCollide, vec3_origin, vec3_angle, &tr ); dots += physcollision->ReadStat(0); //results[i] = tr.endpos; } } else { testType = 0; CBaseEntity *pWorld = GetContainingEntity( INDEXENT(0) ); trace_t tr; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { UTIL_TraceModel( start, targets[i], -size[j], size[j], pWorld, COLLISION_GROUP_NONE, &tr ); //results[i] = tr.endpos; } } duration += engine->Time() - startTime; } test[testType] = duration; Msg("%d collisions in %.2f ms (%u dots)\n", NUM_COLLISION_TESTS, duration*1000, dots ); Msg("Current speed ratio: %.2fX BSP:JGJK\n", test[1] / test[0] ); #if 0 int red = 255, green = 0, blue = 0; for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) { NDebugOverlay::Line( start, results[i], red, green, blue, false, 2 ); } #endif }
//----------------------------------------------------------------------------- // Purpose: Allow pre-frame adjustments on the player //----------------------------------------------------------------------------- void CHL1_Player::PreThink(void) { CheckExplosionEffects(); if ( player_showpredictedposition.GetBool() ) { Vector predPos; UTIL_PredictedPosition( this, player_showpredictedposition_timestep.GetFloat(), &predPos ); NDebugOverlay::Box( predPos, NAI_Hull::Mins( GetHullType() ), NAI_Hull::Maxs( GetHullType() ), 0, 255, 0, 0, 0.01f ); NDebugOverlay::Line( GetAbsOrigin(), predPos, 0, 255, 0, 0, 0.01f ); } int buttonsChanged; buttonsChanged = m_afButtonPressed | m_afButtonReleased; g_pGameRules->PlayerThink( this ); if ( g_fGameOver || IsPlayerLockedInPlace() ) return; // intermission or finale ItemPreFrame( ); WaterMove(); if ( g_pGameRules && g_pGameRules->FAllowFlashlight() ) m_Local.m_iHideHUD &= ~HIDEHUD_FLASHLIGHT; else m_Local.m_iHideHUD |= HIDEHUD_FLASHLIGHT; // checks if new client data (for HUD and view control) needs to be sent to the client UpdateClientData(); CheckTimeBasedDamage(); CheckSuitUpdate(); if (m_lifeState >= LIFE_DYING) { PlayerDeathThink(); return; } // So the correct flags get sent to client asap. // if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE ) AddFlag( FL_ONTRAIN ); else RemoveFlag( FL_ONTRAIN ); // Train speed control if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE ) { CBaseEntity *pTrain = GetGroundEntity(); float vel; if ( pTrain ) { if ( !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) ) pTrain = NULL; } if ( !pTrain ) { if ( GetActiveWeapon() && (GetActiveWeapon()->ObjectCaps() & FCAP_DIRECTIONAL_USE) ) { m_iTrain = TRAIN_ACTIVE | TRAIN_NEW; if ( m_nButtons & IN_FORWARD ) { m_iTrain |= TRAIN_FAST; } else if ( m_nButtons & IN_BACK ) { m_iTrain |= TRAIN_BACK; } else { m_iTrain |= TRAIN_NEUTRAL; } return; } else { trace_t trainTrace; // Maybe this is on the other side of a level transition UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-38), MASK_PLAYERSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trainTrace ); if ( trainTrace.fraction != 1.0 && trainTrace.m_pEnt ) pTrain = trainTrace.m_pEnt; if ( !pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(GetContainingEntity(pev)) ) { // Warning( "In train mode with no train!\n" ); m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE; m_iTrain = TRAIN_NEW|TRAIN_OFF; return; } } } else if ( !( GetFlags() & FL_ONGROUND ) || pTrain->HasSpawnFlags( SF_TRACKTRAIN_NOCONTROL ) || (m_nButtons & (IN_MOVELEFT|IN_MOVERIGHT) ) ) { // Turn off the train if you jump, strafe, or the train controls go dead m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE; m_iTrain = TRAIN_NEW|TRAIN_OFF; return; } SetAbsVelocity( vec3_origin ); vel = 0; if ( m_afButtonPressed & IN_FORWARD ) { vel = 1; pTrain->Use( this, this, USE_SET, (float)vel ); } else if ( m_afButtonPressed & IN_BACK ) { vel = -1; pTrain->Use( this, this, USE_SET, (float)vel ); } if (vel) { m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed()); m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; } } else if (m_iTrain & TRAIN_ACTIVE) { m_iTrain = TRAIN_NEW; // turn off train } // THIS CODE DOESN'T SEEM TO DO ANYTHING!!! // WHY IS IT STILL HERE? (sjb) if (m_nButtons & IN_JUMP) { // If on a ladder, jump off the ladder // else Jump Jump(); } // If trying to duck, already ducked, or in the process of ducking if ((m_nButtons & IN_DUCK) || (GetFlags() & FL_DUCKING) || (m_afPhysicsFlags & PFLAG_DUCKING) ) Duck(); // // If we're not on the ground, we're falling. Update our falling velocity. // if ( !( GetFlags() & FL_ONGROUND ) ) { m_Local.m_flFallVelocity = -GetAbsVelocity().z; } if ( m_afPhysicsFlags & PFLAG_ONBARNACLE ) { SetAbsVelocity( vec3_origin ); } // StudioFrameAdvance( );//!!!HACKHACK!!! Can't be hit by traceline when not animating? //Find targets for NPC to shoot if they decide to miss us FindMissTargets(); }