//----------------------------------------------------------------------------- // Purpose: Creates a flame and attaches it to a target entity. // Input : pTarget - //----------------------------------------------------------------------------- CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMaterialName, float flStartTime, int nDissolveType, bool *pRagdollCreated ) { if ( pRagdollCreated ) { *pRagdollCreated = false; } if ( !pMaterialName ) { pMaterialName = DISSOLVE_SPRITE_NAME; } if ( pTarget->IsPlayer() ) { // Simply immediately kill the player. CBasePlayer *pPlayer = assert_cast< CBasePlayer* >( pTarget ); pPlayer->SetArmorValue( 0 ); CTakeDamageInfo info( pPlayer, pPlayer, pPlayer->GetHealth(), DMG_GENERIC | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); pPlayer->TakeDamage( info ); return NULL; } CEntityDissolve *pDissolve = (CEntityDissolve *) CreateEntityByName( "env_entity_dissolver" ); if ( pDissolve == NULL ) return NULL; pDissolve->m_nDissolveType = nDissolveType; if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) { if ( pTarget->IsNPC() && pTarget->MyNPCPointer()->CanBecomeRagdoll() ) { CTakeDamageInfo info; CBaseEntity *pRagdoll = CreateServerRagdoll( pTarget->MyNPCPointer(), 0, info, COLLISION_GROUP_DEBRIS, true ); pRagdoll->SetCollisionBounds( pTarget->CollisionProp()->OBBMins(), pTarget->CollisionProp()->OBBMaxs() ); // Necessary to cause it to do the appropriate death cleanup if ( pTarget->m_lifeState == LIFE_ALIVE ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); pTarget->TakeDamage( ragdollInfo ); } if ( pRagdollCreated ) { *pRagdollCreated = true; } UTIL_Remove( pTarget ); pTarget = pRagdoll; } } pDissolve->SetModelName( AllocPooledString(pMaterialName) ); pDissolve->AttachToEntity( pTarget ); pDissolve->SetStartTime( flStartTime ); pDissolve->Spawn(); // Send to the client even though we don't have a model pDissolve->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); // Play any appropriate noises when we start to dissolve if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) { pTarget->DispatchResponse( "TLK_ELECTROCUTESCREAM" ); } else { pTarget->DispatchResponse( "TLK_DISSOLVESCREAM" ); } return pDissolve; }
//----------------------------------------------------------------------------- // Purpose: Input handler for showing the message and/or playing the sound. //----------------------------------------------------------------------------- void CEnvInstructorHint::InputShowHint( inputdata_t &inputdata ) { static int s_InstructorServerHintEventCreate = 0; IGameEvent * event = gameeventmanager->CreateEvent( "instructor_server_hint_create", false, &s_InstructorServerHintEventCreate ); if ( event ) { CBaseEntity *pTargetEntity = gEntList.FindEntityByName( NULL, m_iszHintTargetEntity ); if( pTargetEntity == NULL && !m_bStatic ) pTargetEntity = inputdata.pActivator; if( pTargetEntity == NULL ) pTargetEntity = GetWorldEntity(); char szColorString[128]; Q_snprintf( szColorString, sizeof( szColorString ), "%.3d,%.3d,%.3d", m_Color.r, m_Color.g, m_Color.b ); int iFlags = 0; iFlags |= (m_iPulseOption == 0) ? 0 : (LOCATOR_ICON_FX_PULSE_SLOW << (m_iPulseOption - 1)); iFlags |= (m_iAlphaOption == 0) ? 0 : (LOCATOR_ICON_FX_ALPHA_SLOW << (m_iAlphaOption - 1)); iFlags |= (m_iShakeOption == 0) ? 0 : (LOCATOR_ICON_FX_SHAKE_NARROW << (m_iShakeOption - 1)); iFlags |= m_bStatic ? LOCATOR_ICON_FX_STATIC : 0; CBasePlayer *pActivator = NULL; bool bFilterByActivator = m_bLocalPlayerOnly; #ifdef INFESTED_DLL CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( inputdata.pActivator ); if ( pMarine ) { pActivator = pMarine->GetCommander(); } #else if ( inputdata.value.StringID() != NULL_STRING ) { CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, inputdata.value.String() ); pActivator = dynamic_cast<CBasePlayer*>( pTarget ); if ( pActivator ) { bFilterByActivator = true; } } else { if ( GameRules()->IsMultiplayer() == false ) { pActivator = UTIL_GetLocalPlayer(); } else { Warning( "Failed to play server side instructor hint: no player specified for hint\n" ); Assert( 0 ); } } #endif const char *pActivatorCaption = m_iszActivatorCaption.ToCStr(); if ( !pActivatorCaption || pActivatorCaption[ 0 ] == '\0' ) { pActivatorCaption = m_iszCaption.ToCStr(); } event->SetString( "hint_name", GetEntityName().ToCStr() ); event->SetString( "hint_replace_key", m_iszReplace_Key.ToCStr() ); event->SetInt( "hint_target", pTargetEntity->entindex() ); event->SetInt( "hint_activator_userid", ( pActivator ? pActivator->GetUserID() : 0 ) ); event->SetInt( "hint_timeout", m_iTimeout ); event->SetString( "hint_icon_onscreen", m_iszIcon_Onscreen.ToCStr() ); event->SetString( "hint_icon_offscreen", m_iszIcon_Offscreen.ToCStr() ); event->SetString( "hint_caption", m_iszCaption.ToCStr() ); event->SetString( "hint_activator_caption", pActivatorCaption ); event->SetString( "hint_color", szColorString ); event->SetFloat( "hint_icon_offset", m_fIconOffset ); event->SetFloat( "hint_range", m_fRange ); event->SetInt( "hint_flags", iFlags ); event->SetString( "hint_binding", m_iszBinding.ToCStr() ); event->SetBool( "hint_allow_nodraw_target", m_bAllowNoDrawTarget ); event->SetBool( "hint_nooffscreen", m_bNoOffscreen ); event->SetBool( "hint_forcecaption", m_bForceCaption ); event->SetBool( "hint_local_player_only", bFilterByActivator ); gameeventmanager->FireEvent( event ); } }
/* <1dfdff> ../cstrike/dlls/tutor.cpp:66 */ void MonitorTutorStatus() { static cvar_t *tutor_enable = NULL; static bool tutor_enableCvarExists = true; bool shouldTutorBeOn = false; int numHumans = 0; if (!tutor_enableCvarExists || s_nextCvarCheckTime > gpGlobals->time) { return; } if (tutor_enable != NULL || (tutor_enable = CVAR_GET_POINTER("tutor_enable")) != NULL) { if (!s_tutorDisabledThisGame && tutor_enable->value > 0.0f) { shouldTutorBeOn = true; } } else tutor_enableCvarExists = false; for (int i = 1; i <= gpGlobals->maxClients; ++i) { CBasePlayer *pPlayer = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i)); if (pPlayer && !pPlayer->IsBot()) { ++numHumans; } } if (shouldTutorBeOn) { if (numHumans <= 1) { if (TheTutor == NULL) { CBasePlayer *localPlayer = UTIL_GetLocalPlayer(); if (localPlayer != NULL) { ClientPrint(localPlayer->pev, HUD_PRINTCENTER, "#CZero_Tutor_Turned_On"); } TheTutor = new CCSTutor; } } else s_tutorDisabledThisGame = true; } else { if (TheTutor != NULL) { CBasePlayer *localPlayer = UTIL_GetLocalPlayer(); if (localPlayer != NULL) { ClientPrint(localPlayer->pev, HUD_PRINTCENTER, "#CZero_Tutor_Turned_Off"); } delete TheTutor; TheTutor = NULL; } } s_nextCvarCheckTime = gpGlobals->time + 1.0f; }
bool ShouldRemoveThisRagdoll( CBaseAnimating *pRagdoll ) { if ( g_RagdollLVManager.IsLowViolence() ) { return true; } #ifdef CLIENT_DLL /* we no longer ignore enemies just because they are on fire -- a ragdoll in front of me is always a higher priority for retention than a flaming zombie behind me. At the time I put this in, the ragdolls do clean up their own effects if culled via SUB_Remove(). If you're encountering trouble with ragdolls leaving effects behind, try renabling the code below. ///////////////////// //Just ignore it until we're done burning/dissolving. if ( pRagdoll->GetEffectEntity() ) return false; */ Vector vMins, vMaxs; Vector origin = pRagdoll->m_pRagdoll->GetRagdollOrigin(); pRagdoll->m_pRagdoll->GetRagdollBounds( vMins, vMaxs ); if( engine->IsBoxInViewCluster( vMins + origin, vMaxs + origin) == false ) { if ( g_debug_ragdoll_removal.GetBool() ) { debugoverlay->AddBoxOverlay( origin, vMins, vMaxs, QAngle( 0, 0, 0 ), 0, 255, 0, 16, 5 ); debugoverlay->AddLineOverlay( origin, origin + Vector( 0, 0, 64 ), 0, 255, 0, true, 5 ); } return true; } else if( engine->CullBox( vMins + origin, vMaxs + origin ) == true ) { if ( g_debug_ragdoll_removal.GetBool() ) { debugoverlay->AddBoxOverlay( origin, vMins, vMaxs, QAngle( 0, 0, 0 ), 0, 0, 255, 16, 5 ); debugoverlay->AddLineOverlay( origin, origin + Vector( 0, 0, 64 ), 0, 0, 255, true, 5 ); } return true; } #else CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if( !UTIL_FindClientInPVS( pRagdoll->edict() ) ) { if ( g_debug_ragdoll_removal.GetBool() ) NDebugOverlay::Line( pRagdoll->GetAbsOrigin(), pRagdoll->GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 255, 0, true, 5 ); return true; } else if( !pPlayer->FInViewCone( pRagdoll ) ) { if ( g_debug_ragdoll_removal.GetBool() ) NDebugOverlay::Line( pRagdoll->GetAbsOrigin(), pRagdoll->GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, 255, true, 5 ); return true; } #endif return false; }
void CSingleplayRules::NPCKilled(CBaseEntity *pVictim, const CTakeDamageInfo &info) { CBasePlayer *pEntity = UTIL_GetLocalPlayer(); if (pVictim->m_isRareEntity) { switch (GetSkillLevel()) { case SKILL_EASY: if (g_fr_economy.GetBool()) { pEntity->AddMoney(3 * sk_money_multiplier1.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(5 * sk_exp_multiplier1.GetInt()); } break; case SKILL_MEDIUM: if (g_fr_economy.GetBool()) { pEntity->AddMoney(3 * sk_money_multiplier2.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(5 * sk_exp_multiplier2.GetInt()); } break; case SKILL_HARD: if (g_fr_economy.GetBool()) { pEntity->AddMoney(3 * sk_money_multiplier3.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(5 * sk_exp_multiplier3.GetInt()); } break; case SKILL_VERYHARD: if (g_fr_economy.GetBool()) { pEntity->AddMoney(3 * sk_money_multiplier4.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(5 * sk_exp_multiplier4.GetInt()); } break; case SKILL_NIGHTMARE: if (g_fr_economy.GetBool()) { pEntity->AddMoney(3 * sk_money_multiplier5.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(5 * sk_exp_multiplier5.GetInt()); } break; } } else { switch (GetSkillLevel()) { case SKILL_EASY: if (g_fr_economy.GetBool()) { pEntity->AddMoney(2 * sk_money_multiplier1.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3 * sk_exp_multiplier1.GetInt()); } break; case SKILL_MEDIUM: if (g_fr_economy.GetBool()) { pEntity->AddMoney(2 * sk_money_multiplier2.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3 * sk_exp_multiplier2.GetInt()); } break; case SKILL_HARD: if (g_fr_economy.GetBool()) { pEntity->AddMoney(2 * sk_money_multiplier3.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3 * sk_exp_multiplier3.GetInt()); } break; case SKILL_VERYHARD: if (g_fr_economy.GetBool()) { pEntity->AddMoney(2 * sk_money_multiplier4.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3 * sk_exp_multiplier4.GetInt()); } break; case SKILL_NIGHTMARE: if (g_fr_economy.GetBool()) { pEntity->AddMoney(2 * sk_money_multiplier5.GetInt()); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3 * sk_exp_multiplier5.GetInt()); } break; } } pEntity->IncrementFragCount(1); #define KILLING_SPREE_AMOUNT 5 #define KILLING_FRENZY_AMOUNT 10 #define OVERKILL_AMOUNT 15 #define RAMPAGE_AMOUNT 20 #define UNSTOPPABLE_AMOUNT 25 #define INCONCEIVABLE_AMOUNT 30 #define INVINCIBLE_AMOUNT 35 #define GODLIKE_AMOUNT 40 if (info.GetInflictor() == pEntity) { if (sv_player_voice.GetBool()) { if (sv_player_voice_kill.GetBool()) { int killvoicerandom = random->RandomInt(0, sv_player_voice_kill_freq.GetInt()); if (killvoicerandom == 0) { pEntity->EmitSound("Player.VoiceKill"); } } } } if (sv_killingspree.GetBool()) { int m_iKillsInSpree = pEntity->FragCount(); if (m_iKillsInSpree == KILLING_SPREE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_KILLINGSPREE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(2); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(3); } } if (m_iKillsInSpree == KILLING_FRENZY_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_KILLINGFRENZY"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(4); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(6); } } if (m_iKillsInSpree == OVERKILL_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_OVERKILL"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(6); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(9); } } if (m_iKillsInSpree == RAMPAGE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_RAMPAGE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(8); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(12); } } if (m_iKillsInSpree == UNSTOPPABLE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_UNSTOPPABLE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(10); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(15); } } if (m_iKillsInSpree == INCONCEIVABLE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_INCONCEIVABLE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(12); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(18); } } if (m_iKillsInSpree == INVINCIBLE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_INVINCIBLE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(14); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(21); } } if (m_iKillsInSpree == GODLIKE_AMOUNT) { CFmtStr hint; hint.sprintf("#Valve_Hud_GODLIKE"); pEntity->ShowLevelMessage(hint.Access()); if (g_fr_economy.GetBool()) { pEntity->AddMoney(16); } if (!g_fr_classic.GetBool()) { pEntity->AddXP(24); } } } if (pVictim->m_isRareEntity) { if (g_fr_classic.GetBool()) { pEntity->LevelUpClassic(); } } }
void CMapzoneEdit::Update() { if (mom_zone_edit.GetBool()) { if (!m_bEditing) { m_nBuildStage = BUILDSTAGE_NONE; m_bEditing = true; } } else { if (m_bEditing) { m_nBuildStage = BUILDSTAGE_NONE; m_bEditing = false; } return; } CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if (!pPlayer) return; trace_t tr; Vector vecFwd; AngleVectors(pPlayer->EyeAngles(), &vecFwd); UTIL_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + vecFwd * m_flReticleDist, MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr); Vector vecAim = tr.endpos; if (mom_zone_grid.GetInt() > 0) VectorSnapToGrid(&vecAim, (float) mom_zone_grid.GetInt()); if (m_nBuildStage >= BUILDSTAGE_START) { Vector vecP2, vecP3, vecP4; if (m_nBuildStage >= BUILDSTAGE_END) { vecP3 = m_vecBuildEnd; } else { vecP3 = vecAim; } vecP3[2] = m_vecBuildStart[2]; // Bottom vecP2[0] = m_vecBuildStart[0]; vecP2[1] = vecP3[1]; vecP2[2] = m_vecBuildStart[2]; vecP4[0] = vecP3[0]; vecP4[1] = m_vecBuildStart[1]; vecP4[2] = m_vecBuildStart[2]; DebugDrawLine(m_vecBuildStart, vecP2, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP2, vecP3, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP3, vecP4, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP4, m_vecBuildStart, 255, 255, 255, true, -1.0f); if (m_nBuildStage >= BUILDSTAGE_END) { Vector vecP5, vecP6, vecP8; m_vecBuildEnd[2] = SnapToGrid(m_vecBuildStart[2] + GetZoneHeightToPlayer(pPlayer), (float) mom_zone_grid.GetInt()); // Top vecP5 = m_vecBuildStart; vecP5.z = m_vecBuildEnd[2]; vecP6 = vecP2; vecP6.z = m_vecBuildEnd[2]; vecP8 = vecP4; vecP8.z = m_vecBuildEnd[2]; DebugDrawLine(vecP5, vecP6, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP6, m_vecBuildEnd, 255, 255, 255, true, -1.0f); DebugDrawLine(m_vecBuildEnd, vecP8, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP8, vecP5, 255, 255, 255, true, -1.0f); // Bottom to top DebugDrawLine(m_vecBuildStart, vecP5, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP2, vecP6, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP3, m_vecBuildEnd, 255, 255, 255, true, -1.0f); DebugDrawLine(vecP4, vecP8, 255, 255, 255, true, -1.0f); } } // Draw surface normal. Makes it a bit easier to see where reticle is hitting. if (tr.DidHit()) { DebugDrawLine(vecAim, vecAim + tr.plane.normal * 24.0f, 0, 0, 255, true, -1.0f); } DrawReticle(&vecAim, (mom_zone_grid.GetInt() > 0) ? ((float) mom_zone_grid.GetInt() / 2.0f) : 8.0f); }
//--------------------------------------------------------- // Returns distance to the nearest BaseCombatCharacter. //--------------------------------------------------------- float CBounceBomb::FindNearestNPC() { float flNearest = (BOUNCEBOMB_WARN_RADIUS * BOUNCEBOMB_WARN_RADIUS) + 1.0; // Assume this search won't find anyone. SetNearestNPC( NULL ); CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); int nAIs = g_AI_Manager.NumAIs(); for ( int i = 0; i < nAIs; i++ ) { CAI_BaseNPC *pNPC = ppAIs[ i ]; if( pNPC->IsAlive() ) { // ignore hidden objects if ( pNPC->IsEffectActive( EF_NODRAW ) ) continue; // Don't bother with NPC's that are below me. if( pNPC->EyePosition().z < GetAbsOrigin().z ) continue; // Disregard things that want to be disregarded if( pNPC->Classify() == CLASS_NONE ) continue; // Disregard bullseyes if( pNPC->Classify() == CLASS_BULLSEYE ) continue; // Disregard turrets if( pNPC->m_iClassname == gm_iszFloorTurretClassname || pNPC->m_iClassname == gm_iszGroundTurretClassname ) continue; float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr(); if( flDist < flNearest ) { // Now do a visibility test. if( FVisible( pNPC, MASK_SOLID_BRUSHONLY ) ) { flNearest = flDist; SetNearestNPC( pNPC ); } } } } // finally, check the player. CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if( pPlayer && !(pPlayer->GetFlags() & FL_NOTARGET) ) { float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) ) { flNearest = flDist; SetNearestNPC( pPlayer ); } } if( m_hNearestNPC.Get() ) { // If sprite is active, update its color to reflect who is nearest. if( IsFriend( m_hNearestNPC ) ) { if( m_bFoeNearest ) { // Changing state to where a friend is nearest. if( IsFriend( m_hNearestNPC ) ) { // Friend UpdateLight( true, 0, 255, 0, 190 ); m_bFoeNearest = false; } } } else // it's a foe { if( !m_bFoeNearest ) { // Changing state to where a foe is nearest. UpdateLight( true, 255, 0, 0, 190 ); m_bFoeNearest = true; } } } return sqrt( flNearest ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, const impactdamagetable_t &table, float energyScale, bool allowStaticDamage, int &damageType, bool bDamageFromHeldObjects ) { damageType = DMG_CRUSH; int otherIndex = !index; // UNDONE: Expose a flag for self-inflicted damage? Can't think of a valid case so far. if ( pEvent->pEntities[0] == pEvent->pEntities[1] ) return 0; if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_NO_NPC_IMPACT_DMG ) { if( pEvent->pEntities[index]->IsNPC() || pEvent->pEntities[index]->IsPlayer() ) { return 0; } } // use implicit velocities on ragdolls since they may have high constraint velocities that aren't actually executed, just pushed through contacts if (( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PART_OF_RAGDOLL) && pEvent->pEntities[index]->IsPlayer() ) { pEvent->pObjects[otherIndex]->GetImplicitVelocity( &pEvent->preVelocity[otherIndex], &pEvent->preAngularVelocity[otherIndex] ); } // Dissolving impact damage results in death always. if ( ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_DMG_DISSOLVE ) && !pEvent->pEntities[index]->IsEFlagSet(EFL_NO_DISSOLVE) ) { damageType |= DMG_DISSOLVE; return 1000; } if ( energyScale <= 0.0f ) return 0; const int gameFlagsNoDamage = FVPHYSICS_CONSTRAINT_STATIC | FVPHYSICS_NO_IMPACT_DMG; // NOTE: Crushing damage is handled by stress calcs in vphysics update functions, this is ONLY impact damage // this is a non-moving object due to a constraint - no damage if ( pEvent->pObjects[otherIndex]->GetGameFlags() & gameFlagsNoDamage ) return 0; // If it doesn't take damage from held objects and the object is being held - no damage if ( !bDamageFromHeldObjects && ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) { // If it doesn't take damage from held objects - no damage if ( !bDamageFromHeldObjects ) return 0; } if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY ) { // UNDONE: Add up mass here for car wheels and prop_ragdoll pieces? IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; int count = pEvent->pEntities[otherIndex]->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) ); for ( int i = 0; i < count; i++ ) { if ( pList[i]->GetGameFlags() & gameFlagsNoDamage ) return 0; } } if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { // players can't damage held objects if ( pEvent->pEntities[otherIndex]->IsPlayer() ) return 0; allowStaticDamage = false; } #if 0 { PhysGetDamageInflictorVelocityStartOfFrame( pEvent->pObjects[otherIndex], pEvent->preVelocity[otherIndex], pEvent->preAngularVelocity[otherIndex] ); } #endif float otherSpeedSqr = pEvent->preVelocity[otherIndex].LengthSqr(); float otherAngSqr = 0; // factor in angular for sharp objects if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_DMG_SLICE ) { otherAngSqr = pEvent->preAngularVelocity[otherIndex].LengthSqr(); } float otherMass = pEvent->pObjects[otherIndex]->GetMass(); if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { // if the player is holding the object, use its real mass (player holding reduced the mass) CBasePlayer *pPlayer = NULL; if ( gpGlobals->maxClients == 1 ) { pPlayer = UTIL_GetLocalPlayer(); } else { // See which MP player is holding the physics object and then use that player to get the real mass of the object. // This is ugly but better than having linkage between an object and its "holding" player. for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) { pPlayer = tempPlayer; break; } } } if ( pPlayer ) { otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); } } // NOTE: sum the mass of each object in this system for the purpose of damage if ( pEvent->pEntities[otherIndex] && (pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY) ) { otherMass = PhysGetEntityMass( pEvent->pEntities[otherIndex] ); } if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_HEAVY_OBJECT ) { otherMass = table.largeMassMin; if ( energyScale < 2.0f ) { energyScale = 2.0f; } } // UNDONE: allowStaticDamage is a hack - work out some method for // breakable props to impact the world and break!! if ( !allowStaticDamage ) { if ( otherMass < table.minMass ) return 0; // check to see if the object is small if ( otherMass < table.smallMassMax && otherSpeedSqr < table.smallMassMinSpeedSqr ) return 0; if ( otherSpeedSqr < table.minSpeedSqr && otherAngSqr < table.minRotSpeedSqr ) return 0; } // Add extra oomph for floating objects if ( pEvent->pEntities[index]->IsFloating() && !pEvent->pEntities[otherIndex]->IsWorld() ) { if ( energyScale < 3.0f ) { energyScale = 3.0f; } } float damage = 0; bool bDebug = false;//(&table == &gDefaultPlayerImpactDamageTable); // don't ever take spin damage from slowly spinning objects if ( otherAngSqr > table.minRotSpeedSqr ) { Vector otherInertia = pEvent->pObjects[otherIndex]->GetInertia(); float angularMom = DotProductAbs( otherInertia, pEvent->preAngularVelocity[otherIndex] ); damage = ReadDamageTable( table.angularTable, table.angularCount, angularMom * energyScale, bDebug ); if ( damage > 0 ) { // Msg("Spin : %.1f, Damage %.0f\n", FastSqrt(angularMom), damage ); damageType |= DMG_SLASH; } } float deltaV = pEvent->preVelocity[index].Length() - pEvent->postVelocity[index].Length(); float mass = pEvent->pObjects[index]->GetMass(); // If I lost speed, and I lost less than min velocity, then filter out this energy if ( deltaV > 0 && deltaV < table.myMinVelocity ) { deltaV = 0; } float eliminatedEnergy = deltaV * deltaV * mass; deltaV = pEvent->preVelocity[otherIndex].Length() - pEvent->postVelocity[otherIndex].Length(); float otherEliminatedEnergy = deltaV * deltaV * otherMass; // exaggerate the effects of really large objects if ( otherMass >= table.largeMassMin ) { otherEliminatedEnergy *= table.largeMassScale; float dz = pEvent->preVelocity[otherIndex].z - pEvent->postVelocity[otherIndex].z; if ( deltaV > 0 && dz < 0 && pEvent->preVelocity[otherIndex].z < 0 ) { float factor = fabs(dz / deltaV); otherEliminatedEnergy *= (1 + factor * (table.largeMassFallingScale - 1.0f)); } } eliminatedEnergy += otherEliminatedEnergy; // now in units of this character's speed squared float invMass = pEvent->pObjects[index]->GetInvMass(); if ( !pEvent->pObjects[index]->IsMoveable() ) { // inv mass is zero, but impact damage is enabled on this // prop, so recompute: invMass = 1.0f / pEvent->pObjects[index]->GetMass(); } else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { // if the player is holding the object, use it's real mass (player holding reduced the mass) CBasePlayer *pPlayer = NULL; if ( gpGlobals->maxClients == 1 ) { pPlayer = UTIL_GetLocalPlayer(); } else { // See which MP player is holding the physics object and then use that player to get the real mass of the object. // This is ugly but better than having linkage between an object and its "holding" player. for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) { pPlayer = tempPlayer; break; } } } if ( pPlayer ) { float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] ); if ( mass > 0 ) { invMass = 1.0f / mass; } } } eliminatedEnergy *= invMass * energyScale; damage += ReadDamageTable( table.linearTable, table.linearCount, eliminatedEnergy, bDebug ); if ( !pEvent->pObjects[otherIndex]->IsStatic() && otherMass < table.smallMassMax && table.smallMassCap > 0 ) { damage = clamp( damage, 0.f, table.smallMassCap ); } return damage; }
void QUA_helicopter::Think(void) { if (!m_bSpawn) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); /*if ( m_bEngineLocked ) { m_bUnableToFire = true; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR; } } else {*/ // Start this as false and update it again each frame //m_bUnableToFire = false; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_VEHICLE_CROSSHAIR; } //} SetNextThink( gpGlobals->curtime ); //StudioFrameAdvance(); if(m_fReloadTime<=gpGlobals->curtime && m_iAmmoCount<40) { m_iAmmoCount++; m_fReloadTime=gpGlobals->curtime+0.5f; } if(m_fCannonCharge<=gpGlobals->curtime && m_iCannonCount<100) { m_iCannonCount++; m_fCannonCharge=gpGlobals->curtime+0.02f; } if ( m_hPlayer ) { /*engine->Con_NPrintf( 10, " " ); engine->Con_NPrintf( 11, "PILOTABLE VEHICLE HELICOPTER" ); engine->Con_NPrintf( 12, " " ); engine->Con_NPrintf( 13, "Cursors : Movement" ); engine->Con_NPrintf( 14, "Duck : Down" ); engine->Con_NPrintf( 15, "Jump : up" ); engine->Con_NPrintf( 16, "Attack 1 : Machine Gun" ); */ Vector vecEyeDir, vecEyePos; m_hPlayer->EyePositionAndVectors( &vecEyePos, &vecEyeDir, NULL, NULL ); // Trace out from the player's eye point. Vector vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH ); trace_t trace; UTIL_TraceLine( vecEyePos, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace ); // See if we hit something, if so, adjust end position to hit location. if ( trace.fraction < 1.0 ) { vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH * trace.fraction ); } //m_vecLookCrosshair = vecEndPos; m_vecGunCrosshair=vecEndPos; //AimPrimaryWeapon( vecEndPos ); } PostThink(); SetNextThink( gpGlobals->curtime); } }
//----------------------------------------------------------------------------- // Purpose: Finds an entity given a procedural name. // Input : szName - The procedural name to search for, should start with '!'. // pSearchingEntity - // pActivator - The activator entity if this was called from an input // or Use handler. //----------------------------------------------------------------------------- CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller ) { // // Check for the name escape character. // if ( szName[0] == '!' ) { const char *pName = szName + 1; // // It is a procedural name, look for the ones we understand. // if ( FStrEq( pName, "player" ) ) { #ifdef SecobMod__Enable_Fixed_Multiplayer_AI return (CBaseEntity *)UTIL_GetLocalPlayer(); #else return (CBaseEntity *)UTIL_PlayerByIndex( 1 ); #endif //SecobMod__Enable_Fixed_Multiplayer_AI } else if ( FStrEq( pName, "pvsplayer" ) ) { if ( pSearchingEntity ) { return CBaseEntity::Instance( UTIL_FindClientInPVS( pSearchingEntity->edict() ) ); } else if ( pActivator ) { // FIXME: error condition? return CBaseEntity::Instance( UTIL_FindClientInPVS( pActivator->edict() ) ); } else { // FIXME: error condition? #ifdef SecobMod__Enable_Fixed_Multiplayer_AI return (CBaseEntity *)UTIL_GetLocalPlayer(); #else return (CBaseEntity *)UTIL_PlayerByIndex( 1 ); #endif //SecobMod__Enable_Fixed_Multiplayer_AI } } else if ( FStrEq( pName, "activator" ) ) { return pActivator; } else if ( FStrEq( pName, "caller" ) ) { return pCaller; } else if ( FStrEq( pName, "picker" ) ) { #ifdef SecobMod__Enable_Fixed_Multiplayer_AI return FindPickerEntity( UTIL_GetLocalPlayer() ); #else return FindPickerEntity( UTIL_PlayerByIndex(1) ); #endif //SecobMod__Enable_Fixed_Multiplayer_AI } else if ( FStrEq( pName, "self" ) ) { return pSearchingEntity; } else { Warning( "Invalid entity search name %s\n", szName ); Assert(0); } } return NULL; }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_AllyManager::CountAllies( int *pTotal, int *pMedics ) { (*pTotal) = (*pMedics) = 0; #ifdef SecobMod__Enable_Fixed_Multiplayer_AI //should be ifndef? //Do nothing here. #else if ( !AI_IsSinglePlayer() ) { // @TODO (toml 10-22-04): no MP support right now return; } const Vector & vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin(); #endif //SecobMod__Enable_Fixed_Multiplayer_AI const Vector & vPlayerPos = UTIL_GetLocalPlayer()->GetAbsOrigin(); CAI_BaseNPC ** ppAIs = g_AI_Manager.AccessAIs(); int nAIs = g_AI_Manager.NumAIs(); for ( int i = 0; i < nAIs; i++ ) { if ( ppAIs[i]->IsAlive() && ppAIs[i]->IsPlayerAlly() ) { // Vital allies do not count. if( ppAIs[i]->Classify() == CLASS_PLAYER_ALLY_VITAL ) continue; // They only count if I can use them. if( ppAIs[i]->HasSpawnFlags(SF_CITIZEN_NOT_COMMANDABLE) ) continue; // They only count if I can use them. #ifdef SecobMod__Enable_Fixed_Multiplayer_AI if( ppAIs[i]->IRelationType( UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin()) ) != D_LI ) continue; #else if( ppAIs[i]->IRelationType( UTIL_GetLocalPlayer() ) != D_LI ) continue; #endif //SecobMod__Enable_Fixed_Multiplayer_AI // Skip distant NPCs #ifdef SecobMod__Enable_Fixed_Multiplayer_AI Vector vNearestPlayerPos = UTIL_GetNearestPlayer(ppAIs[i]->GetAbsOrigin())->GetAbsOrigin(); if ( !ppAIs[i]->IsInPlayerSquad() && !UTIL_FindClientInPVS( ppAIs[i]->edict() ) && ( ( ppAIs[i]->GetAbsOrigin() - vNearestPlayerPos ).LengthSqr() > 150*12 || fabsf( ppAIs[i]->GetAbsOrigin().z - vNearestPlayerPos.z ) > 192 ) ) continue; #else if ( !ppAIs[i]->IsInPlayerSquad() && !UTIL_FindClientInPVS( ppAIs[i]->edict() ) && ( ( ppAIs[i]->GetAbsOrigin() - vPlayerPos ).LengthSqr() > 150*12 || fabsf( ppAIs[i]->GetAbsOrigin().z - vPlayerPos.z ) > 192 ) ) continue; #endif //SecobMod__Enable_Fixed_Multiplayer_AI if( FClassnameIs( ppAIs[i], "npc_citizen" ) ) { CNPC_Citizen *pCitizen = assert_cast<CNPC_Citizen *>(ppAIs[i]); if ( !pCitizen->CanJoinPlayerSquad() ) continue; if ( pCitizen->WasInPlayerSquad() && !pCitizen->IsInPlayerSquad() ) continue; if ( ppAIs[i]->HasSpawnFlags( SF_CITIZEN_MEDIC ) ) (*pMedics)++; } (*pTotal)++; } } }
//----------------------------------------------------------------------------- // Purpose: Allows the turret to fire on targets if they're visible //----------------------------------------------------------------------------- void CNPC_RocketTurret::FollowThink( void ) { // Default to player as enemy if ( GetEnemy() == NULL ) { SetEnemy( UTIL_GetLocalPlayer() ); } SetSequence ( LookupSequence( "idle" ) ); //Allow descended classes a chance to do something before the think function if ( PreThink() || GetEnemy() == NULL ) { return; } //Update our think time SetNextThink( gpGlobals->curtime + ROCKET_TURRET_THINK_RATE ); UpdateAimPoint(); m_vecGoalAngles = m_vecAnglesToEnemy; // Chase enemy if ( !m_bHasSightOfEnemy ) { // Aim at the last known location m_vecGoalAngles = m_vecCurrentAngles; // Lost sight, move to search think SetThink( &CNPC_RocketTurret::SearchThink ); } //Turn to face UpdateFacing(); // If our facing direction hits our enemy, fire the beam Ray_t rayDmg; Vector vForward; AngleVectors( m_vecCurrentAngles, &vForward, NULL, NULL ); Vector vEndPoint = EyePosition() + vForward*ROCKET_TURRET_RANGE; rayDmg.Init( EyePosition(), vEndPoint ); rayDmg.m_IsRay = true; trace_t traceDmg; // This version reorients through portals CTraceFilterSimple subfilter( this, COLLISION_GROUP_NONE ); CTraceFilterTranslateClones filter ( &subfilter ); float flRequiredParameter = 2.0f; CProp_Portal* pFirstPortal = UTIL_Portal_FirstAlongRay( rayDmg, flRequiredParameter ); UTIL_Portal_TraceRay_Bullets( pFirstPortal, rayDmg, MASK_VISIBLE_AND_NPCS, &filter, &traceDmg, false ); if ( traceDmg.m_pEnt ) { // This thing we're hurting is our enemy if ( traceDmg.m_pEnt == GetEnemy() ) { // If we're past the cooldown time, fire another rocket if ( (gpGlobals->curtime - m_flTimeLastFired) > ROCKET_TURRET_ROCKET_FIRE_COOLDOWN_TIME ) { SetThink( &CNPC_RocketTurret::LockingThink ); } } } }
void CNPC_RocketTurret::Activate( void ) { m_filterBeams.SetPassEntity( this ); m_filterBeams.SetPassEntity2( UTIL_GetLocalPlayer() ); BaseClass::Activate(); }
//----------------------------------------------------------------------------- // Purpose: // Input : &data - //----------------------------------------------------------------------------- void CItem_DynamicResupply::InputCalculateType( inputdata_t &data ) {{ #ifdef SecobMod__Enable_Fixed_Multiplayer_AI // spawn gear for the nearest player CBasePlayer *pNearest = UTIL_GetNearestPlayer(GetAbsOrigin()); if ( pNearest != NULL ) SpawnDynamicItem( pNearest ); #else CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); SpawnDynamicItem( pPlayer ); #endif //SecobMod__Enable_Fixed_Multiplayer_AI } //----------------------------------------------------------------------------- // Purpose: // Input : &data - //----------------------------------------------------------------------------- void CItem_DynamicResupply::InputBecomeMaster( inputdata_t &data ) { if ( g_MasterResupply ) g_MasterResupply->m_bIsMaster = false; g_MasterResupply = this; m_bIsMaster = true; // Stop thinking now that I am the master. SetThink( NULL ); } //----------------------------------------------------------------------------- // 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"); } 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: //----------------------------------------------------------------------------- void CItem_DynamicResupply::FindPotentialItems( int nCount, DynamicResupplyItems_t *pItems, int iDebug, SpawnInfo_t *pSpawnInfo ) { int i; for ( i = 0; i < nCount; ++i ) { pSpawnInfo[i].m_iPotentialItems = 0; } // Count the potential addition of items in the PVS CBaseEntity *pEntity = NULL; while ( (pEntity = UTIL_EntitiesInPVS( this, pEntity )) != NULL ) { if ( pEntity->WorldSpaceCenter().DistToSqr( WorldSpaceCenter() ) > (POTENTIAL_ITEM_RADIUS * POTENTIAL_ITEM_RADIUS) ) continue; for ( i = 0; i < nCount; ++i ) { if ( !FClassnameIs( pEntity, pItems[i].sEntityName ) ) continue; if ( iDebug == 2 ) { NDebugOverlay::Line( WorldSpaceCenter(), pEntity->WorldSpaceCenter(), 0,255,0, true, 20.0 ); } ++pSpawnInfo[i].m_iPotentialItems; break; } } if ( iDebug ) { Msg("Searching the PVS:\n"); for ( int i = 0; i < nCount; i++ ) { Msg(" Found %d '%s' in the PVS.\n", pSpawnInfo[i].m_iPotentialItems, pItems[i].sEntityName ); } } }
// pBeam->SetEndWidth( 0.05f ); // Higher brightness means less transparent pBeam->SetBrightness(255); pBeam->SetColor(255, 185 + random->RandomInt(-16, 16), 40); pBeam->RelinkBeam(); // The beam should only exist for a very short time pBeam->LiveForTime(0.1f); } void CWeaponMomentumGun::DoImpactEffect(trace_t &tr, int nDamageType) { //Draw our beam DrawBeam(tr.startpos, tr.endpos, 15.5); if ((tr.surface.flags & SURF_SKY) == false) { CPVSFilter filter(tr.endpos); te->GaussExplosion(filter, 0.0f, tr.endpos, tr.plane.normal, 0); //m_nBulletType = GetAmmoDef()->Index("GaussEnergy"); //UTIL_ImpactTrace(&tr, m_nBulletType); } } CON_COMMAND(holster_weapon, "Holster test.") { CBasePlayer* pPlayer = UTIL_GetLocalPlayer(); if (pPlayer) { CBaseCombatWeapon* active = pPlayer->GetActiveWeapon(); active->SetWeaponVisible(!active->IsWeaponVisible()); } }
/* <1ef79d> ../cstrike/dlls/career_tasks.cpp:385 */ void CCareerTask::__MAKE_VHOOK(OnEvent)(GameEventType event, CBasePlayer *pVictim, CBasePlayer *pAttacker) { if (m_isComplete) return; if (event == m_event) { if ((m_defuser && !pAttacker->m_bIsDefusing) || (m_vip && !pAttacker->m_bIsVIP)) return; if (m_rescuer) { int hostages_ = 0; CBaseEntity *hostageEntity = NULL; while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL) { if (hostageEntity->pev->takedamage != DAMAGE_YES) continue; CHostage *hostage = static_cast<CHostage *>(hostageEntity); if (!hostage->IsFollowingSomeone()) continue; if (hostage->IsValid() && hostage->m_target == pAttacker) ++hostages_; } if (!hostages_) { return; } } if (m_event != EVENT_KILL || (!m_weaponId && !m_weaponClassId) && m_event != EVENT_HEADSHOT || (!m_weaponId && !m_weaponClassId) && m_event != EVENT_PLAYER_TOOK_DAMAGE || (!m_weaponId && !m_weaponClassId)) { if (m_event == EVENT_ROUND_WIN) { if (!Q_strcmp(m_name, "defendhostages")) { int hostages_ = 0; CBaseEntity *hostageEntity = NULL; while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL) { if (hostageEntity->pev->takedamage != 1.0f && hostageEntity->pev->deadflag != DEAD_DEAD) ++hostages_; } if (!hostages_) { ++m_eventsSeen; SendPartialNotification(); } } else if (!Q_strcmp(m_name, "hostagessurvive")) { int hostages_ = 0; CBaseEntity *hostageEntity = NULL; while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL) { CHostage *hostage = (CHostage *)hostageEntity; if (hostage && hostage->IsDead()) ++hostages_; } if (!hostages_) { ++m_eventsSeen; SendPartialNotification(); } } else if (!Q_strcmp(m_name, "winfast")) { if (m_eventsNeeded >= TheCareerTasks->GetRoundElapsedTime()) { m_eventsSeen = m_eventsNeeded; SendPartialNotification(); } } else if (IsTaskCompletableThisRound()) { ++m_eventsSeen; SendPartialNotification(); } } else { ++m_eventsSeen; SendPartialNotification(); } } } if (event == m_event && !m_mustLive && m_eventsSeen >= m_eventsNeeded && IsTaskCompletableThisRound()) { CBasePlayer *player = UTIL_GetLocalPlayer(); EMIT_SOUND(ENT(player->pev), CHAN_VOICE, "events/task_complete.wav", VOL_NORM, ATTN_NORM); m_isComplete = true; MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer); WRITE_STRING("TASKDONE"); WRITE_BYTE(m_id); MESSAGE_END(); if (TheTutor != NULL) { TheTutor->OnEvent(EVENT_CAREER_TASK_DONE); } UTIL_LogPrintf("Career Task Done %d\n", m_id); if (m_event == EVENT_ROUND_WIN && !Q_strcmp(m_name, "winfast")) { TheCareerTasks->SetFinishedTaskTime((int)TheCareerTasks->GetRoundElapsedTime()); UTIL_GetLocalPlayer()->SyncRoundTimer(); } } else if (event >= EVENT_ROUND_DRAW) { if (event > EVENT_ROUND_LOSS) { if (event == EVENT_DIE && (m_mustLive || m_crossRounds)) { m_eventsSeen = 0; SendPartialNotification(); m_diedThisRound = true; } } else if (m_mustLive) { if (m_eventsSeen >= m_eventsNeeded && !m_diedThisRound && IsTaskCompletableThisRound()) { CBasePlayer *player = UTIL_GetLocalPlayer(); EMIT_SOUND(ENT(player->pev), CHAN_VOICE, "events/task_complete.wav", VOL_NORM, ATTN_NORM); m_isComplete = true; MESSAGE_BEGIN(MSG_ALL, gmsgCZCareer); WRITE_STRING("TASKDONE"); WRITE_BYTE(m_id); MESSAGE_END(); UTIL_LogPrintf("Career Task Done %d\n", m_id); if (m_event == EVENT_ROUND_WIN && !Q_strcmp(m_name, "winfast")) { TheCareerTasks->SetFinishedTaskTime((int)TheCareerTasks->GetRoundElapsedTime()); UTIL_GetLocalPlayer()->SyncRoundTimer(); } if (TheTutor != NULL) { TheTutor->OnEvent(EVENT_CAREER_TASK_DONE); } } m_diedThisRound = false; if (m_mustLive) { m_eventsSeen = 0; SendPartialNotification(); } } } }
//--------------------------------------------------------- // Count of all the weapons in the world of my type and // see if we have a surplus. If there is a surplus, try // to find suitable candidates for removal. // // Right now we just remove the first weapons we find that // are behind the player, or are out of the player's PVS. // Later, we may want to score the results so that we // removed the farthest gun that's not in the player's // viewcone, etc. // // Some notes and thoughts: // // This code is designed NOT to remove weapons that are // hand-placed by level designers. It should only clean // up weapons dropped by dead NPCs, which is useful in // situations where enemies are spawned in for a sustained // period of time. // // Right now we PREFER to remove weapons that are not in the // player's PVS, but this could be opposite of what we // really want. We may only want to conduct the cleanup on // weapons that are IN the player's PVS. //--------------------------------------------------------- void CGameWeaponManager::Think() { int i; // Don't have to think all that often. SetNextThink( gpGlobals->curtime + 2.0 ); const char *pszWeaponName = STRING( m_iszWeaponName ); CUtlVector<CBaseEntity *> candidates( 0, 64 ); if ( m_bExpectingWeapon ) { CBaseCombatWeapon *pWeapon = NULL; // Firstly, count the total number of weapons of this type in the world. // Also count how many of those can potentially be removed. pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName )); while( pWeapon ) { if( !pWeapon->IsEffectActive( EF_NODRAW ) && pWeapon->IsRemoveable() ) { candidates.AddToTail( pWeapon ); } pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName )); } } else { for ( i = 0; i < m_ManagedNonWeapons.Count(); i++) { CBaseEntity *pEntity = m_ManagedNonWeapons[i]; if ( pEntity ) { Assert( pEntity->m_iClassname == m_iszWeaponName ); if ( !pEntity->IsEffectActive( EF_NODRAW ) ) { candidates.AddToTail( pEntity ); } } else { m_ManagedNonWeapons.FastRemove( i-- ); } } } // Calculate the surplus. int surplus = candidates.Count() - m_iMaxPieces; // Based on what the player can see, try to clean up the world by removing weapons that // the player cannot see right at the moment. CBaseEntity *pCandidate; for ( i = 0; i < candidates.Count() && surplus > 0; i++ ) { bool fRemovedOne = false; pCandidate = candidates[i]; Assert( !pCandidate->IsEffectActive( EF_NODRAW ) ); if ( gpGlobals->maxClients == 1 ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); // Nodraw serves as a flag that this weapon is already being removed since // all we're really doing inside this loop is marking them for removal by // the entity system. We don't want to count the same weapon as removed // more than once. if( !UTIL_FindClientInPVS( pCandidate->edict() ) ) { fRemovedOne = true; } else if( !pPlayer->FInViewCone( pCandidate ) ) { fRemovedOne = true; } else if ( UTIL_DistApprox( pPlayer->GetAbsOrigin(), pCandidate->GetAbsOrigin() ) > (30*12) ) { fRemovedOne = true; } } else { fRemovedOne = true; } if( fRemovedOne ) { pCandidate->AddEffects( EF_NODRAW ); UTIL_Remove( pCandidate ); DevMsg( 2, "Surplus %s removed\n", pszWeaponName); surplus--; } } }
void CNPC_Hydra::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_HYDRA_DEPLOY: { m_flHeadGoalInfluence = 1.0; float dist = (EyePosition() - m_vecHeadGoal).Length(); if (dist < m_idealSegmentLength) { TaskComplete(); } AimHeadInTravelDirection( 0.2 ); } break; case TASK_HYDRA_PREP_STAB: { int i; if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } CBaseEntity *pTarget = GetTarget(); if (pTarget == NULL) { TaskFail( FAIL_NO_TARGET ); } if (pTarget->IsPlayer()) { m_vecTarget = pTarget->EyePosition( ); } else { m_vecTarget = pTarget->BodyTarget( EyePosition( ) ); } float distToTarget = (m_vecTarget - m_vecHeadGoal).Length(); float distToBase = (m_vecHeadGoal - GetAbsOrigin()).Length(); m_idealLength = distToTarget + distToBase * 0.5; if (m_idealLength > HYDRA_MAX_LENGTH) m_idealLength = HYDRA_MAX_LENGTH; if (distToTarget < 100.0) { m_vecTargetDir = (m_vecTarget - m_vecHeadGoal); VectorNormalize( m_vecTargetDir ); m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (100 - distToTarget) * 0.5; } else if (distToTarget > 200.0) { m_vecTargetDir = (m_vecTarget - m_vecHeadGoal); VectorNormalize( m_vecTargetDir ); m_vecHeadGoal = m_vecHeadGoal - m_vecTargetDir * (200.0 - distToTarget) * 0.5; } // face enemy m_vecTargetDir = (m_vecTarget - m_body[m_body.Count()-1].vecPos); VectorNormalize( m_vecTargetDir ); m_vecHeadDir = m_vecHeadDir * 0.6 + m_vecTargetDir * 0.4; VectorNormalize( m_vecHeadDir.GetForModify() ); // build tension towards strike time float influence = 1.0 - (m_flTaskEndTime - gpGlobals->curtime) / pTask->flTaskData; if (influence > 1) influence = 1.0; influence = influence * influence * influence; m_flHeadGoalInfluence = influence; // keep head segment straight i = m_body.Count() - 2; m_body[i].vecGoalPos = m_vecHeadGoal - m_vecHeadDir * m_body[i].flActualLength; m_body[i].flGoalInfluence = influence; // curve neck into spiral float distBackFromHead = m_body[i].flActualLength; Vector right, up; VectorVectors( m_vecHeadDir, right, up ); for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--) { distBackFromHead += m_body[i].flActualLength; float r = (distBackFromHead / 200) * 3.1415 * 2; // spiral Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 0.5 + cos( r ) * m_body[i].flActualLength * right + sin( r ) * m_body[i].flActualLength * up; // base r = (distBackFromHead / m_idealLength) * 3.1415 * 0.2; r = sin( r ); p0 = p0 * (1 - r) + r * GetAbsOrigin(); m_body[i].vecGoalPos = p0; m_body[i].flGoalInfluence = influence * (1.0 - (distBackFromHead / distToTarget)); /* if ( (pEnemy->EyePosition( ) - m_body[i].vecPos).Length() < distBackFromHead) { if ( gpGlobals->curtime - m_flLastAttackTime > 4.0) { TaskComplete(); } return; } */ } // look to see if any of the goal positions are stuck for (i = i; i < m_body.Count() - 1; i++) { if (m_body[i].bStuck) { Vector delta = DotProduct( m_body[i].vecGoalPos - m_body[i].vecPos, m_vecHeadDir) * m_vecHeadDir; m_vecHeadGoal -= delta * m_body[i].flGoalInfluence; break; } } if ( gpGlobals->curtime >= m_flTaskEndTime ) { if (distToTarget < 500) { TaskComplete( ); return; } else { TaskFail( "target is too far away" ); return; } } } return; case TASK_HYDRA_STAB: { int i; if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } if (m_flTaskEndTime <= gpGlobals->curtime) { TaskComplete( ); return; } m_flHeadGoalInfluence = 1.0; // face enemy //m_vecHeadDir = (pEnemy->EyePosition( ) - m_body[m_body.Count()-1].vecPos); //VectorNormalize( m_vecHeadDir.GetForModify() ); // keep head segment straight i = m_body.Count() - 2; m_body[i].vecGoalPos = m_vecHeadGoal + m_vecHeadDir * m_body[i].flActualLength; m_body[i].flGoalInfluence = 1.0; Vector vecToTarget = (m_vecTarget - EyePosition( )); // check to see if we went past target if (DotProduct( vecToTarget, m_vecHeadDir ) < 0.0) { TaskComplete( ); return; } float distToTarget = vecToTarget.Length(); float distToBase = (EyePosition( ) - GetAbsOrigin()).Length(); m_idealLength = distToTarget + distToBase; /* if (distToTarget < 20) { m_vecHeadGoal = m_vecTarget; SetLastAttackTime( gpGlobals->curtime ); TaskComplete(); return; } else */ { // hit enemy m_vecHeadGoal = m_vecTarget + m_vecHeadDir * 300; } if (m_idealLength > HYDRA_MAX_LENGTH) m_idealLength = HYDRA_MAX_LENGTH; // curve neck into spiral float distBackFromHead = m_body[i].flActualLength; Vector right, up; VectorVectors( m_vecHeadDir, right, up ); #if 1 for (i = i - 1; i > 1 && distBackFromHead < distToTarget; i--) { Vector p0 = m_vecHeadGoal - m_vecHeadDir * distBackFromHead * 1.0; m_body[i].vecGoalPos = p0; if ((m_vecTarget - m_body[i].vecPos).Length() > distToTarget + distBackFromHead) { m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget); } else { m_body[i].vecGoalPos = EyePosition( ) - m_vecHeadDir * distBackFromHead; m_body[i].flGoalInfluence = 1.0 - (distBackFromHead / distToTarget); } distBackFromHead += m_body[i].flActualLength; } #endif } return; case TASK_HYDRA_PULLBACK: { if (m_body.Count() < 2) { TaskFail( "hydra is too short to begin stab" ); return; } CBaseEntity *pEnemy = (CBaseEntity *)UTIL_GetLocalPlayer(); if (GetEnemy() != NULL) { pEnemy = GetEnemy(); } AimHeadInTravelDirection( 0.2 ); // float dist = (EyePosition() - m_vecHeadGoal).Length(); if (m_flCurrentLength < m_idealLength + m_idealSegmentLength) { TaskComplete(); } } break; default: BaseClass::RunTask( pTask ); break; } }
// CONSIDER: if player in water state, autoset and underwater soundscape? void CEnvSoundscape::Update() { UpdatePlayersInPVS(); if ( !IsEnabled() ) return; for ( int i=0; i < m_hPlayersInPVS.Count(); i++ ) { CBasePlayer *pPlayer = m_hPlayersInPVS[i]; if ( !pPlayer ) continue; if ( !InRangeOfPlayer( pPlayer ) ) continue; // check to see if this is the sound entity that is // currently affecting this player audioparams_t &audio = pPlayer->GetAudioParams(); // if we got this far, we're looking at an entity that is contending // for current player sound. the closest entity to player wins. CEnvSoundscape *pCurrent = (CEnvSoundscape *)audio.ent.Get(); if ( !pCurrent || !pCurrent->IsEnabled() || !pCurrent->InRangeOfPlayer( pPlayer ) ) { // The old one is obscured or out of range.. take over. WriteAudioParamsTo( audio ); } else if ( pCurrent && EarPosition().DistTo( pPlayer->EarPosition() ) < pCurrent->EarPosition().DistTo( pPlayer->EarPosition() ) ) { // new entity is closer to player, so it wins. WriteAudioParamsTo( audio ); } } if ( soundscape_debug.GetBool() ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( pPlayer ) { audioparams_t &audio = pPlayer->GetAudioParams(); if ( audio.ent.Get() != this ) { if ( InRangeOfPlayer( pPlayer ) ) { NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 255,255, true, 0.1 ); } else { NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 0,0, true, 0.1 ); } } else { if ( InRangeOfPlayer( pPlayer ) ) { NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 0, 255,0, true, 0.1 ); } else { NDebugOverlay::Line( GetAbsOrigin(), pPlayer->WorldSpaceCenter(), 255, 170,0, true, 0.1 ); } } } } }
void CC_Mom_ZoneMark(const CCommand &args) { if (!mom_zone_edit.GetBool()) return; CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if (!pPlayer) return; int zonetype = -1; if (g_MapzoneEdit.GetBuildStage() >= BUILDSTAGE_END) { if (args.ArgC() > 1) { zonetype = g_MapzoneEdit.ShortNameToZoneType(args[1]); } else { zonetype = g_MapzoneEdit.ShortNameToZoneType(mom_zone_defzone.GetString()); } if (zonetype == MOMZONETYPE_START || zonetype == MOMZONETYPE_STOP) { // Count zones to make sure we don't create multiple instances. int startnum = 0; int endnum = 0; CBaseEntity *pEnt; pEnt = gEntList.FindEntityByClassname(NULL, "trigger_momentum_timer_start"); while (pEnt) { startnum++; pEnt = gEntList.FindEntityByClassname(pEnt, "trigger_momentum_timer_start"); } pEnt = gEntList.FindEntityByClassname(NULL, "trigger_momentum_timer_stop"); while (pEnt) { endnum++; pEnt = gEntList.FindEntityByClassname(pEnt, "trigger_momentum_timer_stop"); } DevMsg("Found %i starts and %i ends (previous)\n", startnum, endnum); if (!mom_zone_ignorewarning.GetBool() && startnum && endnum) { g_MapzoneEdit.SetBuildStage(BUILDSTAGE_NONE); ConMsg("Map already has a start and an end! Use mom_zone_defzone to set another type.\n"); return; } //The user is trying to make multiple starts? if (zonetype == MOMZONETYPE_START) { // Switch between start and end. zonetype = (startnum <= endnum) ? MOMZONETYPE_START : MOMZONETYPE_STOP; } //else the zonetype can be STOP, allowing for multiple stop triggers to be created } } trace_t tr; Vector vecFwd; AngleVectors(pPlayer->EyeAngles(), &vecFwd); UTIL_TraceLine(pPlayer->EyePosition(), pPlayer->EyePosition() + vecFwd * g_MapzoneEdit.GetZoom(), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr); g_MapzoneEdit.Build(&tr.endpos, zonetype); }
void CHL1NPCTalker::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_HL1TALKER_FOLLOW_WALK_PATH_FOR_UNITS: { float distance; distance = (m_vecLastPosition - GetLocalOrigin()).Length2D(); // Walk path until far enough away if ( distance > pTask->flTaskData || GetNavigator()->GetGoalType() == GOALTYPE_NONE ) { TaskComplete(); GetNavigator()->ClearGoal(); // Stop moving } break; } case TASK_TALKER_CLIENT_STARE: case TASK_TALKER_LOOK_AT_CLIENT: { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); // track head to the client for a while. if ( m_NPCState == NPC_STATE_IDLE && !IsMoving() && !GetExpresser()->IsSpeaking() ) { if ( pPlayer ) { IdleHeadTurn( pPlayer ); } } else { // started moving or talking TaskFail( "moved away" ); return; } if ( pTask->iTask == TASK_TALKER_CLIENT_STARE ) { // fail out if the player looks away or moves away. if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST ) { // player moved away. TaskFail( NO_TASK_FAILURE ); } Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); if ( UTIL_DotPoints( pPlayer->GetAbsOrigin(), GetAbsOrigin(), vForward ) < m_flFieldOfView ) { // player looked away TaskFail( "looked away" ); } } if ( gpGlobals->curtime > m_flWaitFinished ) { TaskComplete( NO_TASK_FAILURE ); } break; } case TASK_WAIT_FOR_MOVEMENT: { if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { // ALERT(at_console, "walking, talking\n"); IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } else if ( GetEnemy() ) { IdleHeadTurn( GetEnemy() ); } BaseClass::RunTask( pTask ); break; } case TASK_FACE_PLAYER: { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( pPlayer ) { //GetMotor()->SetIdealYaw( pPlayer->GetAbsOrigin() ); IdleHeadTurn( pPlayer ); if ( gpGlobals->curtime > m_flWaitFinished && GetMotor()->DeltaIdealYaw() < 10 ) { TaskComplete(); } } else { TaskFail( FAIL_NO_PLAYER ); } break; } case TASK_TALKER_EYECONTACT: { if (!IsMoving() && GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { // ALERT( at_console, "waiting %f\n", m_flStopTalkTime - gpGlobals->time ); IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } BaseClass::RunTask( pTask ); break; } default: { if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } else if ( GetEnemy() && m_NPCState == NPC_STATE_COMBAT ) { IdleHeadTurn( GetEnemy() ); } else if ( GetFollowTarget() ) { IdleHeadTurn( GetFollowTarget() ); } BaseClass::RunTask( pTask ); break; } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPCEventResponseSystem::FrameUpdatePreEntityThink() { if ( !m_ActiveEvents.Count() || !AI_IsSinglePlayer() || !UTIL_GetLocalPlayer() ) return; if ( m_flNextEventPoll > gpGlobals->curtime ) return; m_flNextEventPoll = gpGlobals->curtime + 0.2; // Move through all events, removing expired ones and finding NPCs for active ones. for ( int i = m_ActiveEvents.First(); i != m_ActiveEvents.InvalidIndex(); ) { float flTime = m_ActiveEvents[i].flEventTime; const char *pResponse = m_ActiveEvents.GetElementName(i); // Save off the next index so we can safely remove this one int iNext = m_ActiveEvents.Next(i); // Should it have expired by now? if ( !m_ActiveEvents[i].bPreventExpiration && (flTime + NPCEVENTRESPONSE_GIVEUP_TIME) < gpGlobals->curtime ) { if ( ai_debug_eventresponses.GetBool() ) { Msg( "NPCEVENTRESPONSE: (%.2f) Removing expired event named: %s\n", gpGlobals->curtime, pResponse ); } m_ActiveEvents.RemoveAt(i); } else if ( m_ActiveEvents[i].flNextResponseTime < gpGlobals->curtime ) { // If we've fired once, and our current event should expire now, then expire. if ( m_ActiveEvents[i].bPreventExpiration && (flTime + NPCEVENTRESPONSE_GIVEUP_TIME) < gpGlobals->curtime ) { if ( ai_debug_eventresponses.GetBool() ) { Msg( "NPCEVENTRESPONSE: (%.2f) Removing expired fired event named: %s\n", gpGlobals->curtime, pResponse ); } m_ActiveEvents.RemoveAt(i); } else { float flNearestDist = NPCEVENTRESPONSE_DISTANCE_SQR; CAI_BaseNPC *pNearestNPC = NULL; Vector vecPlayerCenter = UTIL_GetLocalPlayer()->WorldSpaceCenter(); // Try and find the nearest NPC to the player CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); for ( int j = 0; j < g_AI_Manager.NumAIs(); j++ ) { if ( ppAIs[j]->CanRespondToEvent( pResponse )) { float flDistToPlayer = ( vecPlayerCenter - ppAIs[j]->WorldSpaceCenter()).LengthSqr(); if ( flDistToPlayer < flNearestDist ) { flNearestDist = flDistToPlayer; pNearestNPC = ppAIs[j]; } } } // Found one? if ( pNearestNPC ) { if ( pNearestNPC->RespondedTo( pResponse, m_ActiveEvents[i].bForce, m_ActiveEvents[i].bCancelScript ) ) { // Don't remove the response yet. Leave it around until the refire time has expired. // This stops repeated firings of the same concept from spamming the NPCs. m_ActiveEvents[i].bPreventExpiration = true; m_ActiveEvents[i].flNextResponseTime = gpGlobals->curtime + NPCEVENTRESPONSE_REFIRE_TIME; if ( ai_debug_eventresponses.GetBool() ) { Msg( "NPCEVENTRESPONSE: (%.2f) Event '%s' responded to by NPC '%s'. Refire available at: %.2f\n", gpGlobals->curtime, pResponse, pNearestNPC->GetDebugName(), m_ActiveEvents[i].flNextResponseTime ); } // Don't issue multiple responses at once return; } } } } i = iNext; } }
CNPCSpawnDestination *CTemplateNPCMaker::FindSpawnDestination() { CNPCSpawnDestination *pDestinations[ MAX_DESTINATION_ENTS ]; CBaseEntity *pEnt = NULL; CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); int count = 0; if( !pPlayer ) { return NULL; } // Collect all the qualifiying destination ents pEnt = gEntList.FindEntityByName( NULL, m_iszDestinationGroup ); if( !pEnt ) { DevWarning("Template NPC Spawner (%s) doesn't have any spawn destinations!\n", GetDebugName() ); return NULL; } while( pEnt ) { CNPCSpawnDestination *pDestination; pDestination = dynamic_cast <CNPCSpawnDestination*>(pEnt); if( pDestination && pDestination->IsAvailable() ) { bool fValid = true; Vector vecTest = pDestination->GetAbsOrigin(); if( m_CriterionVisibility != TS_YN_DONT_CARE ) { // Right now View Cone check is omitted intentionally. Vector vecTopOfHull = NAI_Hull::Maxs( HULL_HUMAN ); vecTopOfHull.x = 0; vecTopOfHull.y = 0; bool fVisible = (pPlayer->FVisible( vecTest ) || pPlayer->FVisible( vecTest + vecTopOfHull ) ); if( m_CriterionVisibility == TS_YN_YES ) { if( !fVisible ) fValid = false; } else { if( fVisible ) { if ( !(pPlayer->GetFlags() & FL_NOTARGET) ) fValid = false; else DevMsg( 2, "Spawner %s spawning even though seen due to notarget\n", STRING( GetEntityName() ) ); } } } if( fValid ) { pDestinations[ count ] = pDestination; count++; } } pEnt = gEntList.FindEntityByName( pEnt, m_iszDestinationGroup ); } if( count < 1 ) return NULL; // Now find the nearest/farthest based on distance criterion if( m_CriterionDistance == TS_DIST_DONT_CARE ) { // Pretty lame way to pick randomly. Try a few times to find a random // location where a hull can fit. Don't try too many times due to performance // concerns. for( int i = 0 ; i < 5 ; i++ ) { CNPCSpawnDestination *pRandomDest = pDestinations[ rand() % count ]; if( HumanHullFits( pRandomDest->GetAbsOrigin() ) ) { return pRandomDest; } } return NULL; } else { if( m_CriterionDistance == TS_DIST_NEAREST ) { float flNearest = FLT_MAX; CNPCSpawnDestination *pNearest = NULL; for( int i = 0 ; i < count ; i++ ) { Vector vecTest = pDestinations[ i ]->GetAbsOrigin(); float flDist = ( vecTest - pPlayer->GetAbsOrigin() ).Length(); if ( m_iMinSpawnDistance != 0 && m_iMinSpawnDistance > flDist ) continue; if( flDist < flNearest && HumanHullFits( vecTest ) ) { flNearest = flDist; pNearest = pDestinations[ i ]; } } return pNearest; } else { float flFarthest = 0; CNPCSpawnDestination *pFarthest = NULL; for( int i = 0 ; i < count ; i++ ) { Vector vecTest = pDestinations[ i ]->GetAbsOrigin(); float flDist = ( vecTest - pPlayer->GetAbsOrigin() ).Length(); if ( m_iMinSpawnDistance != 0 && m_iMinSpawnDistance > flDist ) continue; if( flDist > flFarthest && HumanHullFits( vecTest ) ) { flFarthest = flDist; pFarthest = pDestinations[ i ]; } } return pFarthest; } } return NULL; }
//----------------------------------------------------------------------------- // Purpose: // Input : &data - //----------------------------------------------------------------------------- void CItem_DynamicResupply::InputCalculateType( inputdata_t &data ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); SpawnDynamicItem( pPlayer ); }
// CONSIDER: if player in water state, autoset and underwater soundscape? void CEnvSoundscape::UpdateForPlayer( ss_update_t &update ) { if ( !IsEnabled() ) { if ( update.pCurrentSoundscape == this ) { update.pCurrentSoundscape = NULL; update.currentDistance = 0; update.bInRange = false; } return; } // calc range from sound entity to player Vector target = EarPosition(); float range = (update.playerPosition - target).Length(); if ( update.pCurrentSoundscape == this ) { update.currentDistance = range; update.bInRange = false; if ( m_flRadius > range || m_flRadius == -1 ) { trace_t tr; update.traceCount++; UTIL_TraceLine( target, update.playerPosition, MASK_SOLID_BRUSHONLY|MASK_WATER, update.pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1 && !tr.startsolid ) { update.bInRange = true; } } } else { if ( (!update.bInRange || range < update.currentDistance ) && (m_flRadius > range || m_flRadius == -1) ) { trace_t tr; update.traceCount++; UTIL_TraceLine( target, update.playerPosition, MASK_SOLID_BRUSHONLY|MASK_WATER, update.pPlayer, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1 && !tr.startsolid ) { audioparams_t &audio = update.pPlayer->GetAudioParams(); WriteAudioParamsTo( audio ); update.pCurrentSoundscape = this; update.bInRange = true; update.currentDistance = range; } } } if ( soundscape_debug.GetBool() ) { // draw myself NDebugOverlay::Box(GetAbsOrigin(), Vector(-10,-10,-10), Vector(10,10,10), 255, 0, 255, 64, NDEBUG_PERSIST_TILL_NEXT_SERVER ); #ifdef SecobMod__Enable_Fixed_Multiplayer_AI CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); #else // Don't use GetLocalPlayer(), because that prevents multiplayer games using this for testing with a single client in the game CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); #endif //SecobMod__Enable_Fixed_Multiplayer_AI if ( update.pPlayer ) { audioparams_t &audio = update.pPlayer->GetAudioParams(); if ( audio.ent.Get() != this ) { if ( InRangeOfPlayer( update.pPlayer ) ) { NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 255, 255, true, NDEBUG_PERSIST_TILL_NEXT_SERVER ); } else { NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 0, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER ); } } else { if ( InRangeOfPlayer( update.pPlayer ) ) { NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 0, 255, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER ); } else { NDebugOverlay::Line( GetAbsOrigin(), update.pPlayer->WorldSpaceCenter(), 255, 170, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER ); } // also draw lines to each sound position. // we don't store the number of local sound positions, just a bitvector of which ones are on. unsigned int soundbits = audio.localBits.Get(); float periodic = 2.0f * sin((fmod(gpGlobals->curtime,2.0f) - 1.0f) * M_PI); // = -4f .. 4f for (int ii = 0 ; ii < NUM_AUDIO_LOCAL_SOUNDS ; ++ii ) { if ( soundbits & (1 << ii) ) { const Vector &soundLoc = audio.localSound.Get(ii); NDebugOverlay::Line( GetAbsOrigin(), soundLoc, 0, 32 , 255 , false, NDEBUG_PERSIST_TILL_NEXT_SERVER ); NDebugOverlay::Cross3D( soundLoc, 16.0f + periodic, 0, 0, 255, false, NDEBUG_PERSIST_TILL_NEXT_SERVER ); } } } } NDebugOverlay::EntityTextAtPosition( GetAbsOrigin(), 0, STRING(m_soundscapeName), NDEBUG_PERSIST_TILL_NEXT_SERVER ); } }
void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION { VPROF( "CRagdollLRURetirement::Update" ); // Compress out dead items int i, next; int iMaxRagdollCount = m_iMaxRagdolls; if ( iMaxRagdollCount == -1 ) { iMaxRagdollCount = g_ragdoll_maxcount.GetInt(); } // fade them all for the low violence version if ( g_RagdollLVManager.IsLowViolence() ) { iMaxRagdollCount = 0; } m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; // First, find ragdolls that are good candidates for deletion because they are not // visible at all, or are in a culled visibility box for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); if ( pRagdoll ) { m_iRagdollCount++; IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if (pObject && !pObject->IsAsleep()) { m_iSimulatedRagdollCount++; } if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true ) { #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); return; } } } else { m_LRU.Remove(i); } } ////////////////////////////// /// EPISODIC ALGORITHM /// ////////////////////////////// // If we get here, it means we couldn't find a suitable ragdoll to remove, // so just remove the furthest one. int furthestOne = m_LRU.Head(); float furthestDistSq = 0; #ifdef CLIENT_DLL C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); #else CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); #endif if (pPlayer && m_LRU.Count() > iMaxRagdollCount) // find the furthest one algorithm { Vector PlayerOrigin = pPlayer->GetAbsOrigin(); // const CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { CBaseAnimating *pRagdoll = m_LRU[i].Get(); next = m_LRU.Next(i); IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; if ( pRagdoll ) { // float distToPlayer = (pPlayer->GetAbsOrigin() - pRagdoll->GetAbsOrigin()).LengthSqr(); float distToPlayer = (PlayerOrigin - pRagdoll->GetAbsOrigin()).LengthSqr(); if (distToPlayer > furthestDistSq) { furthestOne = i; furthestDistSq = distToPlayer; } } else // delete bad rags first. { furthestOne = i; break; } } #ifdef CLIENT_DLL m_LRU[ furthestOne ]->SUB_Remove(); #else m_LRU[ furthestOne ]->SUB_StartFadeOut( 0 ); #endif } else // fall back on old-style pick the oldest one algorithm { for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { if ( m_LRU.Count() <= iMaxRagdollCount ) break; next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropAPC2::Think( void ) { if (!m_bSpawn) { if(m_fReloadTime<=gpGlobals->curtime && m_iAmmoCount<50) { m_iAmmoCount++; m_fReloadTime=gpGlobals->curtime+0.5f; } if(m_fCannonCharge<=gpGlobals->curtime && m_iCannonCount<100) { m_iCannonCount++; m_fCannonCharge=gpGlobals->curtime+0.03f; } BaseClass::Think(); CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( m_bEngineLocked ) { m_bUnableToFire = true; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR; } } else { // Start this as false and update it again each frame m_bUnableToFire = false; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_VEHICLE_CROSSHAIR; } } SetNextThink( gpGlobals->curtime ); if ( !m_bInitialHandbrake ) // after initial timer expires, set the handbrake { m_bInitialHandbrake = true; m_VehiclePhysics.SetHandbrake( true ); m_VehiclePhysics.Think(); } StudioFrameAdvance(); if ( IsSequenceFinished() ) { int iSequence = SelectWeightedSequence( ACT_IDLE ); if ( iSequence > ACTIVITY_NOT_AVAILABLE ) { SetCycle( 0 ); m_flAnimTime = gpGlobals->curtime; ResetSequence( iSequence ); ResetClientsideFrame(); } } if ( m_hPlayer && !m_bExitAnimOn && !m_bEnterAnimOn ) { Vector vecEyeDir, vecEyePos; m_hPlayer->EyePositionAndVectors( &vecEyePos, &vecEyeDir, NULL, NULL ); // Trace out from the player's eye point. Vector vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH ); trace_t trace; UTIL_TraceLine( vecEyePos, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace ); // See if we hit something, if so, adjust end position to hit location. if ( trace.fraction < 1.0 ) { vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH * trace.fraction ); } //m_vecLookCrosshair = vecEndPos; m_vecGunCrosshair=vecEndPos; AimPrimaryWeapon( vecEndPos ); //GetRocketShootPosition( &vecEndPos ); if ( m_hLaserDot != NULL ) { Vector laserPos = trace.endpos; m_hLaserDot->SetAbsOrigin(laserPos); if ( trace.DidHitNonWorldEntity() ) { CBaseEntity *pHit = trace.m_pEnt; if ( ( pHit != NULL ) && ( pHit->m_takedamage ) ) { SetLaserDotTarget( m_hLaserDot, pHit ); EnableLaserDot( m_hLaserDot, pHit != NULL ); } else { SetLaserDotTarget( m_hLaserDot, NULL ); EnableLaserDot(m_hLaserDot,true); } } else { SetLaserDotTarget( m_hLaserDot, NULL ); EnableLaserDot(m_hLaserDot,true); } } } } }