void CASW_Drone_Movement::SetGroundEntity( CBaseEntity *newGround ) { CBaseEntity *oldGround = m_pNPC->GetGroundEntity(); Vector vecBaseVelocity = m_pNPC->GetBaseVelocity(); if ( !oldGround && newGround ) { // Subtract ground velocity at instant we hit ground jumping vecBaseVelocity -= newGround->GetAbsVelocity(); vecBaseVelocity.z = newGround->GetAbsVelocity().z; } else if ( oldGround && !newGround ) { // Add in ground velocity at instant we started jumping vecBaseVelocity += oldGround->GetAbsVelocity(); vecBaseVelocity.z = oldGround->GetAbsVelocity().z; } // TODO //else if ( oldGround && newGround && oldGround != newGround ) //{ // subtract old and add new ground velocity? When might his occur, who knows? ywb 9/24/03 //} m_pNPC->SetBaseVelocity( vecBaseVelocity ); m_pNPC->SetGroundEntity( newGround ); }
void CHL2GameMovement::SetGroundEntity( CBaseEntity *newGround ) { CBaseEntity *oldGround = player->GetGroundEntity(); Vector vecBaseVelocity = player->GetBaseVelocity(); //Adrian: Special case for combine balls. if ( newGround && newGround->GetCollisionGroup() == HL2COLLISION_GROUP_COMBINE_BALL_NPC ) { return; } else if ( !oldGround && newGround ) { // Subtract ground velocity at instant we hit ground jumping vecBaseVelocity -= newGround->GetAbsVelocity(); vecBaseVelocity.z = newGround->GetAbsVelocity().z; } else if ( oldGround && !newGround ) { // Add in ground velocity at instant we started jumping vecBaseVelocity += oldGround->GetAbsVelocity(); vecBaseVelocity.z = oldGround->GetAbsVelocity().z; } player->SetBaseVelocity( vecBaseVelocity ); player->SetGroundEntity( newGround ); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::UpdatePlayerDopplerShift( ) { // ----------------------------- // make rotor, engine sounds // ----------------------------- if (m_iSoundState == 0) { // Sound startup. InitializeRotorSound(); } else { CBaseEntity *pPlayer = NULL; // UNDONE: this needs to send different sounds to every player for multiplayer. // FIXME: this isn't the correct way to find a player!!! pPlayer = gEntList.FindEntityByName( NULL, "!player" ); if (pPlayer) { Vector dir; VectorSubtract( pPlayer->GetAbsOrigin(), GetAbsOrigin(), dir ); VectorNormalize(dir); #if 1 float velReceiver = DotProduct( pPlayer->GetAbsVelocity(), dir ); float velTransmitter = -DotProduct( GetAbsVelocity(), dir ); // speed of sound == 13049in/s int iPitch = (int)(100 * ((1 - velReceiver / 13049) / (1 + velTransmitter / 13049))); #else // This is a bogus doppler shift, but I like it better float relV = DotProduct( GetAbsVelocity() - pPlayer->GetAbsVelocity(), dir ); int iPitch = (int)(100 + relV / 50.0); #endif // clamp pitch shifts if (iPitch > 250) { iPitch = 250; } if (iPitch < 50) { iPitch = 50; } UpdateRotorSoundPitch( iPitch ); // Msg( "Pitch:%d\n", iPitch ); } else { Msg( "Chopper didn't find a player!\n" ); } } }
void CWeaponBaseGun::ProcessAnimationEvents() { // Lowers the weapon once the player goes faster than the limit speed // Credit: This is a modified version of // https://developer.valvesoftware.com/wiki/Lowering_your_weapon_on_sprint // If we currently don't want the weapon to ever lower, don't calculate it. Easy if (!mom_weapon_speed_lower_enable.GetBool()) return; CBaseEntity *pOwner = GetOwnerEntity(); // With pOwner being just CBaseEntity, we allow the replay entity to also lower its weapon! if (!pOwner) return; vec_t pCurrent2DVelocitySqr = pOwner->GetAbsVelocity().Length2DSqr(); float pThresholdSpeed = mom_weapon_speed_lower.GetFloat(); // Don't simplify this. Seriously. if ((!m_bWeaponIsLowered || (m_bWeaponIsLowered && GetIdealActivity() == ACT_VM_IDLE)) && pCurrent2DVelocitySqr >= pThresholdSpeed * pThresholdSpeed) // pow is faster than a square root { /* The rht of the OR takes care of the weapon being not lowered after shooting. Note how it's not * GetIdealActivity() != ACT_VM_IDLE_LOWERED so we don't change the firing animation! * It takes a bit until the weapon lowers itself again (IDLE is not set instantly) but that's perfect! */ m_bWeaponIsLowered = true; SendWeaponAnim(ACT_VM_IDLE_LOWERED); } else if (m_bWeaponIsLowered && pCurrent2DVelocitySqr < pThresholdSpeed * pThresholdSpeed) { m_bWeaponIsLowered = false; SendWeaponAnim(ACT_VM_IDLE); } }
void TransferChildren( CBaseEntity *pOldParent, CBaseEntity *pNewParent ) { CBaseEntity *pChild = pOldParent->FirstMoveChild(); while ( pChild ) { // NOTE: Have to do this before the unlink to ensure local coords are valid Vector vecAbsOrigin = pChild->GetAbsOrigin(); QAngle angAbsRotation = pChild->GetAbsAngles(); Vector vecAbsVelocity = pChild->GetAbsVelocity(); // QAngle vecAbsAngVelocity = pChild->GetAbsAngularVelocity(); UnlinkChild( pOldParent, pChild ); LinkChild( pNewParent, pChild ); // FIXME: This is a hack to guarantee update of the local origin, angles, etc. pChild->m_vecAbsOrigin.Init( FLT_MAX, FLT_MAX, FLT_MAX ); pChild->m_angAbsRotation.Init( FLT_MAX, FLT_MAX, FLT_MAX ); pChild->m_vecAbsVelocity.Init( FLT_MAX, FLT_MAX, FLT_MAX ); pChild->SetAbsOrigin(vecAbsOrigin); pChild->SetAbsAngles(angAbsRotation); pChild->SetAbsVelocity(vecAbsVelocity); // pChild->SetAbsAngularVelocity(vecAbsAngVelocity); pChild = pOldParent->FirstMoveChild(); } }
int CFuncShootBoost::OnTakeDamage(const CTakeDamageInfo &info) { CBaseEntity *pInflictor = info.GetAttacker(); if (pInflictor) { Vector finalVel = m_vPushDir.Normalized() * m_fPushForce; switch (m_iIncrease) { case 0: break; case 1: finalVel += pInflictor->GetAbsVelocity(); break; case 2: if (finalVel.LengthSqr() < pInflictor->GetAbsVelocity().LengthSqr()) finalVel = pInflictor->GetAbsVelocity(); break; case 3: // The description of this method says the player velocity is increaed by final velocity, // but we're just adding one vec to the other, which is not quite the same if (finalVel.LengthSqr() < pInflictor->GetAbsVelocity().LengthSqr()) finalVel += pInflictor->GetAbsVelocity(); break; case 4: pInflictor->SetBaseVelocity(finalVel); break; default: DevWarning("CFuncShootBoost:: %i not recognised as valid for m_iIncrease", m_iIncrease); break; } if (m_Destination) { if (((CBaseTrigger *) m_Destination)->IsTouching(pInflictor)) { pInflictor->SetAbsVelocity(finalVel); } } else { pInflictor->SetAbsVelocity(finalVel); } } // As we don't want to break it, we don't call BaseClass::OnTakeDamage(info); // OnTakeDamage returns the damage dealt return info.GetDamage(); }
// This was the virtual void, overriding it for snow friction void CMomentumGameMovement::SetGroundEntity(trace_t *pm) { //CMomentumPlayer *player = GetMomentumPlayer(); CBaseEntity *newGround = pm ? pm->m_pEnt : NULL; CBaseEntity *oldGround = player->GetGroundEntity(); Vector vecBaseVelocity = player->GetBaseVelocity(); if (!oldGround && newGround) { // Subtract ground velocity at instant we hit ground jumping vecBaseVelocity -= newGround->GetAbsVelocity(); vecBaseVelocity.z = newGround->GetAbsVelocity().z; } else if (oldGround && !newGround) { // Add in ground velocity at instant we started jumping vecBaseVelocity += oldGround->GetAbsVelocity(); vecBaseVelocity.z = oldGround->GetAbsVelocity().z; } player->SetBaseVelocity(vecBaseVelocity); player->SetGroundEntity(newGround); // If we are on something... if (newGround) { CategorizeGroundSurface(*pm);//Snow friction override // Then we are not in water jump sequence player->m_flWaterJumpTime = 0; // Standing on an entity other than the world, so signal that we are touching something. if (!pm->DidHitWorld()) { MoveHelper()->AddToTouched(*pm, mv->m_vecVelocity); } mv->m_vecVelocity.z = 0.0f; } }
void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent ) { CPASAttenuationFilter filter( this ); switch( pEvent->event ) { case GARG_AE_SLASH_LEFT: { // HACKHACK!!! CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH ); if (pHurt) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) { pHurt->ViewPunch( QAngle( -30, -30, 30 ) ); Vector vRight; AngleVectors( GetAbsAngles(), NULL, &vRight, NULL ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 ); } EmitSound( filter, entindex(), "Garg.AttackHit" ); } else // Play a random attack miss sound { EmitSound( filter, entindex(),"Garg.AttackMiss" ); } } break; case GARG_AE_RIGHT_FOOT: case GARG_AE_LEFT_FOOT: UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START ); EmitSound( filter, entindex(), "Garg.Footstep" ); break; case GARG_AE_STOMP: StompAttack(); m_seeTime = gpGlobals->curtime + 12; break; case GARG_AE_BREATHE: EmitSound( filter, entindex(), "Garg.Breath" ); break; default: BaseClass::HandleAnimEvent(pEvent); break; } }
void CGargantua::HandleAnimEvent(AnimEvent_t& event) { switch( event.event ) { case GARG_AE_SLASH_LEFT: { // HACKHACK!!! CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, gSkillData.GetGargantuaDmgSlash(), DMG_SLASH ); if (pHurt) { if ( pHurt->GetFlags().Any( FL_MONSTER | FL_CLIENT ) ) { pHurt->SetPunchAngle( Vector( -30, // pitch -30, // yaw 30 //roll ) ); //UTIL_MakeVectors( GetAbsAngles() ); // called by CheckTraceHullAttack pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - gpGlobals->v_right * 100 ); } EMIT_SOUND_DYN ( this, CHAN_WEAPON, pAttackHitSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) ); } else // Play a random attack miss sound EMIT_SOUND_DYN ( this, CHAN_WEAPON, pAttackMissSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + RANDOM_LONG(0,15) ); Vector forward; UTIL_MakeVectorsPrivate( GetAbsAngles(), &forward, nullptr, nullptr ); } break; case GARG_AE_RIGHT_FOOT: case GARG_AE_LEFT_FOOT: UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 750 ); EMIT_SOUND_DYN ( this, CHAN_BODY, pFootSounds[ RANDOM_LONG(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) ); break; case GARG_AE_STOMP: StompAttack(); m_seeTime = gpGlobals->time + 12; break; case GARG_AE_BREATHE: EMIT_SOUND_DYN ( this, CHAN_VOICE, pBreatheSounds[ RANDOM_LONG(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + RANDOM_LONG(-10,10) ); break; default: CBaseMonster::HandleAnimEvent( event ); break; } }
void CNPC_Gargantua::HandleAnimEvent( animevent_t *pEvent ) { CPASAttenuationFilter filter( this ); switch( pEvent->event ) { case GARG_AE_SLASH_LEFT: { // HACKHACK!!! CBaseEntity *pHurt = GargantuaCheckTraceHullAttack( GARG_ATTACKDIST + 10.0, sk_gargantua_dmg_slash.GetFloat(), DMG_SLASH ); if (pHurt) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) { pHurt->ViewPunch( QAngle( -30, -30, 30 ) ); Vector vRight; AngleVectors( GetAbsAngles(), NULL, &vRight, NULL ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - vRight * 100 ); } enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackHitSounds[ random->RandomInt(0,ARRAYSIZE(pAttackHitSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) ); } else // Play a random attack miss sound enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, pAttackMissSounds[ random->RandomInt(0,ARRAYSIZE(pAttackMissSounds)-1) ], 1.0, ATTN_NORM, 0, 50 + random->RandomInt(0,15) ); } break; case GARG_AE_RIGHT_FOOT: case GARG_AE_LEFT_FOOT: UTIL_ScreenShake( GetAbsOrigin(), 4.0, 3.0, 1.0, 1500, SHAKE_START ); enginesound->EmitSound( filter, entindex(), CHAN_BODY, pFootSounds[ random->RandomInt(0,ARRAYSIZE(pFootSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) ); break; case GARG_AE_STOMP: StompAttack(); m_seeTime = gpGlobals->curtime + 12; break; case GARG_AE_BREATHE: enginesound->EmitSound( filter, entindex(), CHAN_VOICE, pBreatheSounds[ random->RandomInt(0,ARRAYSIZE(pBreatheSounds)-1) ], 1.0, ATTN_GARG, 0, PITCH_NORM + random->RandomInt(-10,10) ); break; default: BaseClass::HandleAnimEvent(pEvent); break; } }
void CGrenadeSpit::Think( void ) { InitHissSound(); if ( m_pHissSound == NULL ) return; // Add a doppler effect to the balls as they travel #ifdef HL2SB CBaseEntity *pPlayer = AI_GetNearestPlayer( GetAbsOrigin() ); #else CBaseEntity *pPlayer = AI_GetSinglePlayer(); #endif if ( pPlayer != NULL ) { Vector dir; VectorSubtract( pPlayer->GetAbsOrigin(), GetAbsOrigin(), dir ); VectorNormalize(dir); float velReceiver = DotProduct( pPlayer->GetAbsVelocity(), dir ); float velTransmitter = -DotProduct( GetAbsVelocity(), dir ); // speed of sound == 13049in/s int iPitch = 100 * ((1 - velReceiver / 13049) / (1 + velTransmitter / 13049)); // clamp pitch shifts if ( iPitch > 250 ) { iPitch = 250; } if ( iPitch < 50 ) { iPitch = 50; } // Set the pitch we've calculated CSoundEnvelopeController::GetController().SoundChangePitch( m_pHissSound, iPitch, 0.1f ); } // Set us up to think again shortly SetNextThink( gpGlobals->curtime + 0.05f ); }
void CMoveHelperClient::ProcessImpacts( void ) { m_pHost->PhysicsTouchTriggers(); // Don't bother if the player ain't solid if ( m_pHost->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) return; // Save off the velocity, cause we need to temporarily reset it Vector vel = m_pHost->GetAbsVelocity(); // Touch other objects that were intersected during the movement. for (int i = 0 ; i < m_TouchList.Count(); i++) { // Run the impact function as if we had run it during movement. C_BaseEntity *entity = ClientEntityList().GetEnt( m_TouchList[i].trace.m_pEnt->entindex() ); if ( !entity ) continue; Assert( entity != m_pHost ); // Don't ever collide with self!!!! if ( entity == m_pHost ) continue; // Reconstruct trace results. m_TouchList[i].trace.m_pEnt = entity; // Use the velocity we had when we collided, so boxes will move, etc. m_pHost->SetAbsVelocity( m_TouchList[i].deltavelocity ); entity->PhysicsImpact( m_pHost, m_TouchList[i].trace ); } // Restore the velocity m_pHost->SetAbsVelocity( vel ); // So no stuff is ever left over, sigh... ResetTouchList(); }
int CWeaponStunStick::WeaponMeleeAttack1Condition( float flDot, float flDist ) { // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!) CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer(); CBaseEntity *pEnemy = pNPC->GetEnemy(); if (!pEnemy) return COND_NONE; Vector vecVelocity; AngularImpulse angVelocity; pEnemy->GetVelocity( &vecVelocity, &angVelocity ); // Project where the enemy will be in a little while, add some randomness so he doesn't always hit float dt = sk_crowbar_lead_time.GetFloat(); dt += random->RandomFloat( -0.3f, 0.2f ); if ( dt < 0.0f ) dt = 0.0f; Vector vecExtrapolatedPos; VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos ); Vector vecDelta; VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta ); if ( fabs( vecDelta.z ) > 70 ) { return COND_TOO_FAR_TO_ATTACK; } Vector vecForward = pNPC->BodyDirection2D( ); vecDelta.z = 0.0f; float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() ); if ((flDot < 0.7) && (flExtrapolatedDot < 0.7)) { return COND_NOT_FACING_ATTACK; } float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() ); if( pEnemy->IsPlayer() ) { //Vector vecDir = pEnemy->GetSmoothedVelocity(); //float flSpeed = VectorNormalize( vecDir ); // If player will be in front of me in one-half second, clock his arse. Vector vecProjectEnemy = pEnemy->GetAbsOrigin() + (pEnemy->GetAbsVelocity() * 0.35); Vector vecProjectMe = GetAbsOrigin(); if( (vecProjectMe - vecProjectEnemy).Length2D() <= 48.0f ) { return COND_CAN_MELEE_ATTACK1; } } /* if( metropolice_move_and_melee.GetBool() ) { if( pNPC->IsMoving() ) { flTargetDist *= 1.5f; } } */ float flTargetDist = 48.0f; if ((flDist > flTargetDist) && (flExtrapolatedDist > flTargetDist)) { return COND_TOO_FAR_TO_ATTACK; } return COND_CAN_MELEE_ATTACK1; }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. //========================================================= void CNPC_Bullsquid::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { case BSQUID_AE_SPIT: { if ( GetEnemy() ) { Vector vSpitPos; QAngle vSpitAngle; GetAttachment( "Mouth", vSpitPos, vSpitAngle); Vector vTarget = GetEnemy()->GetAbsOrigin(); Vector vToss; CBaseEntity* pBlocker; float flGravity = sv_gravity.GetFloat() * SPIT_GRAVITY; ThrowLimit(vSpitPos, vTarget, flGravity, 3, Vector(0,0,0), Vector(0,0,0), GetEnemy(), &vToss, &pBlocker); CGrenadeSpit *pGrenade = (CGrenadeSpit*)CreateNoSpawn( "grenade_spit", vSpitPos, vec3_angle, this ); //pGrenade->KeyValue( "velocity", vToss ); pGrenade->Spawn( ); pGrenade->SetOwner( this ); pGrenade->SetOwnerEntity( this ); pGrenade->SetSpitSize( 2 ); pGrenade->SetAbsVelocity( vToss ); // Tumble through the air pGrenade->SetLocalAngularVelocity( QAngle( random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ), random->RandomFloat ( -100, -500 ) ) ); AttackSound(); CPVSFilter filter( vSpitPos ); te->SpriteSpray( filter, 0.0, &vSpitPos, &vToss, m_nSquidSpitSprite, 5, 10, 15 ); } } break; case BSQUID_AE_BITE: { // SOUND HERE! CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_bite.GetFloat(), DMG_SLASH ); if ( pHurt ) { Vector forward, up; AngleVectors( GetAbsAngles(), &forward, NULL, &up ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - (forward * 100) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); pHurt->RemoveFlag( FL_ONGROUND ); } } break; case BSQUID_AE_WHIP_SND: { EmitSound( "NPC_Bullsquid.TailWhip" ); break; } /* case BSQUID_AE_TAILWHIP: { CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_whip.GetFloat(), DMG_SLASH | DMG_ALWAYSGIB ); if ( pHurt ) { Vector right, up; AngleVectors( GetAbsAngles(), NULL, &right, &up ); if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 20, 0, -20 ) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (right * 200) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); } } break; */ case BSQUID_AE_BLINK: { // close eye. m_nSkin = 1; } break; case BSQUID_AE_HOP: { float flGravity = sv_gravity.GetFloat(); // throw the squid up into the air on this frame. if ( GetFlags() & FL_ONGROUND ) { RemoveFlag( FL_ONGROUND ); } // jump into air for 0.8 (24/30) seconds Vector vecVel = GetAbsVelocity(); vecVel.z += ( 0.625 * flGravity ) * 0.5; SetAbsVelocity( vecVel ); } break; case BSQUID_AE_THROW: { // squid throws its prey IF the prey is a client. CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), 0, 0 ); if ( pHurt ) { pHurt->ViewPunch( QAngle(20,0,-20) ); // screeshake transforms the viewmodel as well as the viewangle. No problems with seeing the ends of the viewmodels. UTIL_ScreenShake( pHurt->GetAbsOrigin(), 25.0, 1.5, 0.7, 2, SHAKE_START ); // If the player, throw him around if ( pHurt->IsPlayer()) { Vector forward, up; AngleVectors( GetLocalAngles(), &forward, NULL, &up ); pHurt->ApplyAbsVelocityImpulse( forward * 300 + up * 300 ); } // If not the player see if has bullsquid throw interatcion else { CBaseCombatCharacter *pVictim = ToBaseCombatCharacter( pHurt ); if (pVictim) { if ( pVictim->HandleInteraction( g_interactionBullsquidThrow, NULL, this ) ) { Vector forward, up; AngleVectors( GetLocalAngles(), &forward, NULL, &up ); pVictim->ApplyAbsVelocityImpulse( forward * 300 + up * 250 ); } } } } } break; default: BaseClass::HandleAnimEvent( pEvent ); } }
//========================================================= // SonicAttack //========================================================= void CNPC_Houndeye::SonicAttack ( void ) { EmitSound( "NPC_Houndeye.SonicAttack" ); if (m_pEnergyWave) { UTIL_Remove(m_pEnergyWave); } Vector vFacingDir = EyeDirection3D( ); m_pEnergyWave = (CEnergyWave*)Create( "energy_wave", EyePosition(), GetLocalAngles() ); m_flEndEnergyWaveTime = gpGlobals->curtime + 1; //<<TEMP>> magic m_pEnergyWave->SetAbsVelocity( 100*vFacingDir ); CBaseEntity *pEntity = NULL; // iterate on all entities in the vicinity. for ( CEntitySphereQuery sphere( GetAbsOrigin(), HOUNDEYE_MAX_ATTACK_RADIUS ); pEntity = sphere.GetCurrentEntity(); sphere.NextEntity() ) { if (pEntity->Classify() == CLASS_HOUNDEYE) { continue; } if (pEntity->GetFlags() & FL_NOTARGET) { continue; } IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if ( pEntity->m_takedamage != DAMAGE_NO || pPhysicsObject) { // -------------------------- // Adjust damage by distance // -------------------------- float flDist = (pEntity->WorldSpaceCenter() - GetAbsOrigin()).Length(); float flDamageAdjuster = 1-( flDist / HOUNDEYE_MAX_ATTACK_RADIUS ); // -------------------------- // Adjust damage by direction // -------------------------- Vector forward; AngleVectors( GetAbsAngles(), &forward ); Vector vEntDir = (pEntity->GetAbsOrigin() - GetAbsOrigin()); VectorNormalize(vEntDir); float flDotPr = DotProduct(forward,vEntDir); flDamageAdjuster *= flDotPr; if (flDamageAdjuster < 0) { continue; } // -------------------------- // Adjust damage by visibility // -------------------------- if ( !FVisible( pEntity ) ) { if ( pEntity->IsPlayer() ) { // if this entity is a client, and is not in full view, inflict half damage. We do this so that players still // take the residual damage if they don't totally leave the houndeye's effective radius. We restrict it to clients // so that monsters in other parts of the level don't take the damage and get pissed. flDamageAdjuster *= 0.5; } else if ( !FClassnameIs( pEntity, "func_breakable" ) && !FClassnameIs( pEntity, "func_pushable" ) ) { // do not hurt nonclients through walls, but allow damage to be done to breakables continue; } } // ------------------------------ // Apply the damage // ------------------------------ if (pEntity->m_takedamage != DAMAGE_NO) { CTakeDamageInfo info( this, this, flDamageAdjuster * sk_Houndeye_dmg_blast.GetFloat(), DMG_SONIC | DMG_ALWAYSGIB ); CalculateExplosiveDamageForce( &info, (pEntity->GetAbsOrigin() - GetAbsOrigin()), pEntity->GetAbsOrigin() ); pEntity->TakeDamage( info ); // Throw the player if ( pEntity->IsPlayer() ) { Vector forward; AngleVectors( GetLocalAngles(), &forward ); Vector vecVelocity = pEntity->GetAbsVelocity(); vecVelocity += forward * 250 * flDamageAdjuster; vecVelocity.z = 300 * flDamageAdjuster; pEntity->SetAbsVelocity( vecVelocity ); pEntity->ViewPunch( QAngle(random->RandomInt(-20,20), 0, random->RandomInt(-20,20)) ); } } // ------------------------------ // Apply physics foces // ------------------------------ IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if (pPhysicsObject) { float flForce = flDamageAdjuster * 8000; pPhysicsObject->ApplyForceCenter( (vEntDir+Vector(0,0,0.2)) * flForce ); pPhysicsObject->ApplyTorqueCenter( vEntDir * flForce ); } } } }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. // // Returns number of events handled, 0 if none. //========================================================= void CNPC_AlienGrunt::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { case AGRUNT_AE_HORNET1: case AGRUNT_AE_HORNET2: case AGRUNT_AE_HORNET3: case AGRUNT_AE_HORNET4: case AGRUNT_AE_HORNET5: { // m_vecEnemyLKP should be center of enemy body Vector vecArmPos; QAngle angArmDir; Vector vecDirToEnemy; QAngle angDir; if (HasCondition( COND_SEE_ENEMY) && GetEnemy()) { Vector vecEnemyLKP = GetEnemy()->GetAbsOrigin(); vecDirToEnemy = ( ( vecEnemyLKP ) - GetAbsOrigin() ); VectorAngles( vecDirToEnemy, angDir ); VectorNormalize( vecDirToEnemy ); } else { angDir = GetAbsAngles(); angDir.x = -angDir.x; Vector vForward; AngleVectors( angDir, &vForward ); vecDirToEnemy = vForward; } DoMuzzleFlash(); // make angles +-180 if (angDir.x > 180) { angDir.x = angDir.x - 360; } // SetBlending( 0, angDir.x ); GetAttachment( "0", vecArmPos, angArmDir ); vecArmPos = vecArmPos + vecDirToEnemy * 32; CPVSFilter filter( GetAbsOrigin() ); te->Sprite( filter, 0.0, &vecArmPos, iAgruntMuzzleFlash, random->RandomFloat( 0.4, 0.8 ), 128 ); CBaseEntity *pHornet = CBaseEntity::Create( "hornet", vecArmPos, QAngle( 0, 0, 0 ), this ); Vector vForward; AngleVectors( angDir, &vForward ); pHornet->SetAbsVelocity( vForward * 300 ); pHornet->SetOwnerEntity( this ); EmitSound( "Weapon_Hornetgun.Single" ); CHL1BaseNPC *pHornetMonster = (CHL1BaseNPC *)pHornet->MyNPCPointer(); if ( pHornetMonster ) { pHornetMonster->SetEnemy( GetEnemy() ); } } break; case AGRUNT_AE_LEFT_FOOT: // left foot { CPASAttenuationFilter filter2( this ); EmitSound( filter2, entindex(), "AlienGrunt.LeftFoot" ); } break; case AGRUNT_AE_RIGHT_FOOT: // right foot { CPASAttenuationFilter filter3( this ); EmitSound( filter3, entindex(), "AlienGrunt.RightFoot" ); } break; case AGRUNT_AE_LEFT_PUNCH: { Vector vecMins = GetHullMins(); Vector vecMaxs = GetHullMaxs(); vecMins.z = vecMins.x; vecMaxs.z = vecMaxs.x; CBaseEntity *pHurt = CheckTraceHullAttack( AGRUNT_MELEE_DIST, vecMins, vecMaxs, sk_agrunt_dmg_punch.GetFloat(), DMG_CLUB ); CPASAttenuationFilter filter4( this ); if ( pHurt ) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( -25, 8, 0) ); Vector vRight; AngleVectors( GetAbsAngles(), NULL, &vRight, NULL ); // OK to use gpGlobals without calling MakeVectors, cause CheckTraceHullAttack called it above. if ( pHurt->IsPlayer() ) { // this is a player. Knock him around. pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + vRight * 250 ); } EmitSound(filter4, entindex(), "AlienGrunt.AttackHit" ); Vector vecArmPos; QAngle angArmAng; GetAttachment( 0, vecArmPos, angArmAng ); SpawnBlood(vecArmPos, g_vecAttackDir, pHurt->BloodColor(), 25);// a little surface blood. } else { // Play a random attack miss sound EmitSound(filter4, entindex(), "AlienGrunt.AttackMiss" ); } } break; case AGRUNT_AE_RIGHT_PUNCH: { Vector vecMins = GetHullMins(); Vector vecMaxs = GetHullMaxs(); vecMins.z = vecMins.x; vecMaxs.z = vecMaxs.x; CBaseEntity *pHurt = CheckTraceHullAttack( AGRUNT_MELEE_DIST, vecMins, vecMaxs, sk_agrunt_dmg_punch.GetFloat(), DMG_CLUB ); CPASAttenuationFilter filter5( this ); if ( pHurt ) { if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 25, 8, 0) ); // OK to use gpGlobals without calling MakeVectors, cause CheckTraceHullAttack called it above. if ( pHurt->IsPlayer() ) { // this is a player. Knock him around. Vector vRight; AngleVectors( GetAbsAngles(), NULL, &vRight, NULL ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + vRight * -250 ); } EmitSound( filter5, entindex(), "AlienGrunt.AttackHit" ); Vector vecArmPos; QAngle angArmAng; GetAttachment( 0, vecArmPos, angArmAng ); SpawnBlood(vecArmPos, g_vecAttackDir, pHurt->BloodColor(), 25);// a little surface blood. } else { // Play a random attack miss sound EmitSound( filter5, entindex(), "AlienGrunt.AttackMiss" ); } } break; default: BaseClass::HandleAnimEvent( pEvent ); break; } }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. //========================================================= void CNPC_Bullsquid::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { case BSQUID_AE_SPIT: { if ( GetEnemy() ) { Vector vecSpitOffset; Vector vecSpitDir; Vector vRight, vUp, vForward; AngleVectors ( GetAbsAngles(), &vForward, &vRight, &vUp ); // !!!HACKHACK - the spot at which the spit originates (in front of the mouth) was measured in 3ds and hardcoded here. // we should be able to read the position of bones at runtime for this info. vecSpitOffset = ( vRight * 8 + vForward * 60 + vUp * 50 ); vecSpitOffset = ( GetAbsOrigin() + vecSpitOffset ); vecSpitDir = ( ( GetEnemy()->BodyTarget( GetAbsOrigin() ) ) - vecSpitOffset ); VectorNormalize( vecSpitDir ); vecSpitDir.x += random->RandomFloat( -0.05, 0.05 ); vecSpitDir.y += random->RandomFloat( -0.05, 0.05 ); vecSpitDir.z += random->RandomFloat( -0.05, 0 ); AttackSound(); CSquidSpit::Shoot( this, vecSpitOffset, vecSpitDir * 900 ); } } break; case BSQUID_AE_BITE: { // SOUND HERE! CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_bite.GetFloat(), DMG_SLASH ); if ( pHurt ) { Vector forward, up; AngleVectors( GetAbsAngles(), &forward, NULL, &up ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - (forward * 100) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); pHurt->SetGroundEntity( NULL ); } } break; case BSQUID_AE_TAILWHIP: { CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_whip.GetFloat(), DMG_SLASH | DMG_ALWAYSGIB ); if ( pHurt ) { Vector right, up; AngleVectors( GetAbsAngles(), NULL, &right, &up ); if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 20, 0, -20 ) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (right * 200) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); } } break; case BSQUID_AE_BLINK: { // close eye. m_nSkin = 1; } break; case BSQUID_AE_HOP: { float flGravity = sv_gravity.GetFloat(); // throw the squid up into the air on this frame. if ( GetFlags() & FL_ONGROUND ) { SetGroundEntity( NULL ); } // jump into air for 0.8 (24/30) seconds Vector vecVel = GetAbsVelocity(); vecVel.z += ( 0.625 * flGravity ) * 0.5; SetAbsVelocity( vecVel ); } break; case BSQUID_AE_THROW: { // squid throws its prey IF the prey is a client. CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), 0, 0 ); if ( pHurt ) { // croonchy bite sound CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Bullsquid.Bite" ); // screeshake transforms the viewmodel as well as the viewangle. No problems with seeing the ends of the viewmodels. UTIL_ScreenShake( pHurt->GetAbsOrigin(), 25.0, 1.5, 0.7, 2, SHAKE_START ); if ( pHurt->IsPlayer() ) { Vector forward, up; AngleVectors( GetAbsAngles(), &forward, NULL, &up ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + forward * 300 + up * 300 ); } } } break; default: BaseClass::HandleAnimEvent( pEvent ); } }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. // // Returns number of events handled, 0 if none. //========================================================= void CNPC_BigMomma::HandleAnimEvent( animevent_t *pEvent ) { CPASAttenuationFilter filter( this ); Vector vecFwd, vecRight, vecUp; QAngle angles; angles = GetAbsAngles(); AngleVectors( angles, &vecFwd, &vecRight, &vecUp ); switch( pEvent->event ) { case BIG_AE_MELEE_ATTACKBR: case BIG_AE_MELEE_ATTACKBL: case BIG_AE_MELEE_ATTACK1: { Vector center = GetAbsOrigin() + vecFwd * 128; Vector mins = center - Vector( 64, 64, 0 ); Vector maxs = center + Vector( 64, 64, 64 ); CBaseEntity *pList[8]; int count = UTIL_EntitiesInBox( pList, 8, mins, maxs, FL_NPC | FL_CLIENT ); CBaseEntity *pHurt = NULL; for ( int i = 0; i < count && !pHurt; i++ ) { if ( pList[i] != this ) { if ( pList[i]->GetOwnerEntity() != this ) { pHurt = pList[i]; } } } if ( pHurt ) { CTakeDamageInfo info( this, this, 15, DMG_CLUB | DMG_SLASH ); CalculateMeleeDamageForce( &info, (pHurt->GetAbsOrigin() - GetAbsOrigin()), pHurt->GetAbsOrigin() ); pHurt->TakeDamage( info ); QAngle newAngles = angles; newAngles.x = 15; if ( pHurt->IsPlayer() ) { ((CBasePlayer *)pHurt)->SetPunchAngle( newAngles ); } switch( pEvent->event ) { case BIG_AE_MELEE_ATTACKBR: // pHurt->pev->velocity = pHurt->pev->velocity + (vecFwd * 150) + Vector(0,0,250) - (vecRight * 200); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 150) + Vector(0,0,250) - (vecRight * 200) ); break; case BIG_AE_MELEE_ATTACKBL: pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 150) + Vector(0,0,250) + (vecRight * 200) ); break; case BIG_AE_MELEE_ATTACK1: pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 220) + Vector(0,0,200) ); break; } pHurt->SetGroundEntity( NULL ); EmitSound( filter, entindex(), "BigMomma.AttackHit" ); } } break; case BIG_AE_SCREAM: EmitSound( filter, entindex(), "BigMomma.Alert" ); break; case BIG_AE_PAIN_SOUND: EmitSound( filter, entindex(), "BigMomma.Pain" ); break; case BIG_AE_ATTACK_SOUND: EmitSound( filter, entindex(), "BigMomma.Attack" ); break; case BIG_AE_BIRTH_SOUND: EmitSound( filter, entindex(), "BigMomma.Birth" ); break; case BIG_AE_SACK: if ( RandomInt(0,100) < 30 ) { EmitSound( filter, entindex(), "BigMomma.Sack" ); } break; case BIG_AE_DEATHSOUND: EmitSound( filter, entindex(), "BigMomma.Die" ); break; case BIG_AE_STEP1: // Footstep left case BIG_AE_STEP3: // Footstep back left EmitSound( filter, entindex(), "BigMomma.FootstepLeft" ); break; case BIG_AE_STEP4: // Footstep back right case BIG_AE_STEP2: // Footstep right EmitSound( filter, entindex(), "BigMomma.FootstepRight" ); break; case BIG_AE_MORTAR_ATTACK1: LaunchMortar(); break; case BIG_AE_LAY_CRAB: LayHeadcrab(); break; case BIG_AE_JUMP_FORWARD: SetGroundEntity( NULL ); SetAbsOrigin(GetAbsOrigin() + Vector ( 0 , 0 , 1) );// take him off ground so engine doesn't instantly reset onground SetAbsVelocity(vecFwd * 200 + vecUp * 500 ); break; case BIG_AE_EARLY_TARGET: { CInfoBM *pTarget = (CInfoBM*) GetTarget(); if ( pTarget ) { pTarget->m_OnAnimationEvent.FireOutput( this, this ); } Remember( bits_MEMORY_FIRED_NODE ); } break; default: BaseClass::HandleAnimEvent( pEvent ); break; } }
void COsprey::Flight( ) { float t = (gpGlobals->time - m_startTime); float scale = 1.0 / m_dTime; float f = UTIL_SplineFraction( t * scale, 1.0 ); Vector pos = (m_pos1 + m_vel1 * t) * (1.0 - f) + (m_pos2 - m_vel2 * (m_dTime - t)) * f; Vector ang = (m_ang1) * (1.0 - f) + (m_ang2) * f; m_velocity = m_vel1 * (1.0 - f) + m_vel2 * f; SetAbsOrigin( pos ); SetAbsAngles( ang ); UTIL_MakeAimVectors( GetAbsAngles() ); float flSpeed = DotProduct( gpGlobals->v_forward, m_velocity ); // float flSpeed = DotProduct( gpGlobals->v_forward, GetAbsVelocity() ); float m_flIdealtilt = (160 - flSpeed) / 10.0; // ALERT( at_console, "%f %f\n", flSpeed, flIdealtilt ); if (m_flRotortilt < m_flIdealtilt) { m_flRotortilt += 0.5; if (m_flRotortilt > 0) m_flRotortilt = 0; } if (m_flRotortilt > m_flIdealtilt) { m_flRotortilt -= 0.5; if (m_flRotortilt < -90) m_flRotortilt = -90; } SetBoneController( 0, m_flRotortilt ); if (m_iSoundState == 0) { EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "apache/ap_rotor4.wav", 1.0, 0.15, 0, 110 ); // EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "apache/ap_whine1.wav", 0.5, 0.2, 0, 110 ); m_iSoundState = SND_CHANGE_PITCH; // hack for going through level transitions } else { CBaseEntity *pPlayer = NULL; pPlayer = UTIL_FindEntityByClassname( NULL, "player" ); // UNDONE: this needs to send different sounds to every player for multiplayer. if (pPlayer) { float pitch = DotProduct( m_velocity - pPlayer->GetAbsVelocity(), (pPlayer->GetAbsOrigin() - GetAbsOrigin()).Normalize() ); pitch = (int)(100 + pitch / 75.0); if (pitch > 250) pitch = 250; if (pitch < 50) pitch = 50; if (pitch == 100) pitch = 101; if (pitch != m_iPitch) { m_iPitch = pitch; EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "apache/ap_rotor4.wav", 1.0, 0.15, SND_CHANGE_PITCH | SND_CHANGE_VOL, pitch); // ALERT( at_console, "%.0f\n", pitch ); } } // EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "apache/ap_whine1.wav", flVol, 0.2, SND_CHANGE_PITCH | SND_CHANGE_VOL, pitch); } }
void CMomentumGameMovement::CategorizePosition(float flReflectNormal) { Vector point; trace_t pm; // Reset this each time we-recategorize, otherwise we have bogus friction when we jump into water and plunge downward really quickly player->m_surfaceFriction = 1.0f; // if the player hull point one unit down is solid, the player // is on ground // see if standing on something solid // Doing this before we move may introduce a potential latency in water detection, but // doing it after can get us stuck on the bottom in water if the amount we move up // is less than the 1 pixel 'threshold' we're about to snap to. Also, we'll call // this several times per frame, so we really need to avoid sticking to the bottom of // water on each call, and the converse case will correct itself if called twice. CheckWater(); // observers don't have a ground entity if (player->IsObserver()) return; float flOffset = 2.0f; point[0] = mv->GetAbsOrigin()[0]; point[1] = mv->GetAbsOrigin()[1]; point[2] = mv->GetAbsOrigin()[2] - flOffset; Vector bumpOrigin; bumpOrigin = mv->GetAbsOrigin(); // Shooting up really fast. Definitely not on ground. // On ladder moving up, so not on ground either // NOTE: 145 is a jump. #define NON_JUMP_VELOCITY 140.0f float zvel = mv->m_vecVelocity[2]; bool bMovingUp = zvel > 0.0f; bool bMovingUpRapidly = zvel > NON_JUMP_VELOCITY; float flGroundEntityVelZ = 0.0f; if (bMovingUpRapidly) { // Tracker 73219, 75878: ywb 8/2/07 // After save/restore (and maybe at other times), we can get a case where we were saved on a lift and // after restore we'll have a high local velocity due to the lift making our abs velocity appear high. // We need to account for standing on a moving ground object in that case in order to determine if we really // are moving away from the object we are standing on at too rapid a speed. Note that CheckJump already sets // ground entity to NULL, so this wouldn't have any effect unless we are moving up rapidly not from the jump button. CBaseEntity *ground = player->GetGroundEntity(); if (ground) { flGroundEntityVelZ = ground->GetAbsVelocity().z; bMovingUpRapidly = (zvel - flGroundEntityVelZ) > NON_JUMP_VELOCITY; } } // Was on ground, but now suddenly am not if (bMovingUpRapidly || (bMovingUp && player->GetMoveType() == MOVETYPE_LADDER)) { SetGroundEntity(NULL); } else { // Try and move down. TryTouchGround(bumpOrigin, point, GetPlayerMins(), GetPlayerMaxs(), MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, pm); // Was on ground, but now suddenly am not. If we hit a steep plane, we are not on ground if (!pm.m_pEnt || pm.plane.normal[2] < 0.7) { // Test four sub-boxes, to see if any of them would have found shallower slope we could actually stand on TryTouchGroundInQuadrants(bumpOrigin, point, MASK_PLAYERSOLID, COLLISION_GROUP_PLAYER_MOVEMENT, pm); if (!pm.m_pEnt || pm.plane.normal[2] < 0.7) { SetGroundEntity(NULL); // probably want to add a check for a +z velocity too! if ((mv->m_vecVelocity.z > 0.0f) && (player->GetMoveType() != MOVETYPE_NOCLIP)) { player->m_surfaceFriction = 0.25f; } } else { if ( flReflectNormal == NO_REFL_NORMAL_CHANGE) { DoLateReflect(); CategorizePosition(1.0f); return; } SetGroundEntity(&pm); } } else { if ( flReflectNormal == NO_REFL_NORMAL_CHANGE ) { DoLateReflect(); CategorizePosition(1.0f); return; } SetGroundEntity(&pm); // Otherwise, point to index of ent under us. } #ifndef CLIENT_DLL // If our gamematerial has changed, tell any player surface triggers that are watching IPhysicsSurfaceProps *physprops = MoveHelper()->GetSurfaceProps(); surfacedata_t *pSurfaceProp = physprops->GetSurfaceData(pm.surface.surfaceProps); char cCurrGameMaterial = pSurfaceProp->game.material; if (!player->GetGroundEntity()) { cCurrGameMaterial = 0; } // Changed? if (player->m_chPreviousTextureType != cCurrGameMaterial) { CEnvPlayerSurfaceTrigger::SetPlayerSurface(player, cCurrGameMaterial); } player->m_chPreviousTextureType = cCurrGameMaterial; #endif } }