void CPlayerPickupController::Init( CBasePlayer *pPlayer, CBaseEntity *pObject ) { m_pPlayer = pPlayer; IPhysicsObject *pPhysics = pObject->VPhysicsGetObject(); Vector position; QAngle angles; pPhysics->GetPosition( &position, &angles ); m_grabController.SetMaxImpulse( Vector(20*100,20*100,20*100), AngularImpulse(20*180,20*180,20*180) ); m_grabController.AttachEntity( pObject, pPhysics, position, angles ); // Holster player's weapon if ( m_pPlayer->GetActiveWeapon() ) { if ( !m_pPlayer->GetActiveWeapon()->Holster() ) { Shutdown(); return; } } m_pPlayer->m_Local.m_iHideHUD |= HIDEHUD_WEAPONS; m_pPlayer->SetUseEntity( this ); matrix3x4_t tmp; ComputePlayerMatrix( tmp ); VectorITransform( position, tmp, m_positionPlayerSpace ); // UNDONE: This algorithm needs a bit more thought. REVISIT. // put the bottom of the object arms' length below eye level // get bottommost point of object Vector bottom = physcollision->CollideGetExtent( pPhysics->GetCollide(), vec3_origin, angles, Vector(0,0,-1) ); // get the real eye origin Vector playerEye = pPlayer->EyePosition(); // move target up so that bottom of object is at PLAYER_HOLD_LEVEL z in local space // float delta = PLAYER_HOLD_LEVEL_EYES - bottom.z - m_positionPlayerSpace.z; float delta = 0; // player can reach down 2ft below his feet float maxPickup = (playerEye.z + PLAYER_HOLD_LEVEL_EYES) - (pPlayer->GetAbsMins().z - PLAYER_REACH_DOWN_DISTANCE); delta = clamp( delta, pPlayer->WorldAlignMins().z, maxPickup ); m_positionPlayerSpace.z += delta; m_anglesPlayerSpace = TransformAnglesToLocalSpace( angles, tmp ); m_anglesPlayerSpace = AlignAngles( m_anglesPlayerSpace, DOT_30DEGREE ); // re-transform and check angles = TransformAnglesToWorldSpace( m_anglesPlayerSpace, tmp ); VectorTransform( m_positionPlayerSpace, tmp, position ); // hackhack: Move up to eye position for the check float saveZ = position.z; position.z = playerEye.z; CheckObjectPosition( position, angles, position ); // move back to original position position.z = saveZ; VectorITransform( position, tmp, m_positionPlayerSpace ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) { Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( pPlayer, vecEye, vecSrc ); // vForward[0] += 0.1f; vForward[2] += 0.1f; Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 1200; Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false ); m_bRedraw = true; WeaponSound( SINGLE ); pPlayer->SetAnimation(PLAYER_ATTACK1); EmitSound( "Weapon_Grenade.Throw" ); m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer ) { #ifndef CLIENT_DLL Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 ); CheckThrowPosition( pPlayer, vecEye, vecSrc ); Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 350 + Vector( 0, 0, 50 ); CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER, false ); if ( pGrenade ) { pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); } #endif WeaponSound( WPN_DOUBLE ); // player "shoot" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); m_bRedraw = true; }
virtual void EmitGrenade( Vector vecSrc, QAngle vecAngles, Vector vecVel, AngularImpulse angImpulse, CBasePlayer *pPlayer, float flLifeTime = GRENADE_FUSE_LENGTH ) { // align the stickgrenade vertically and spin end over end QAngle vecNewAngles = QAngle(45,pPlayer->EyeAngles().y,0); AngularImpulse angNewImpulse = AngularImpulse( 0, 600, 0 ); CDODStickGrenade::Create( vecSrc, vecNewAngles, vecVel, angNewImpulse, pPlayer, flLifeTime, GetWeaponID() ); }
bool CBounceBomb::IsValidLocation() { CBaseEntity *pAvoidObject = NULL; float flAvoidForce = 0.0f; CAI_Hint *pHint; CHintCriteria criteria; criteria.SetHintType( HINT_WORLD_INHIBIT_COMBINE_MINES ); criteria.SetFlag( bits_HINT_NODE_NEAREST ); criteria.AddIncludePosition( GetAbsOrigin(), 12.0f * 15.0f ); pHint = CAI_HintManager::FindHint( GetAbsOrigin(), criteria ); if( pHint ) { pAvoidObject = pHint; flAvoidForce = 120.0f; } else { // Look for other mines that are too close to me. CBaseEntity *pEntity = gEntList.FirstEnt(); Vector vecMyPosition = GetAbsOrigin(); while( pEntity ) { if( pEntity->m_iClassname == m_iClassname && pEntity != this ) { // Don't lock down if I'm near a mine that's already locked down. if( vecMyPosition.DistToSqr(pEntity->GetAbsOrigin()) < MINE_MIN_PROXIMITY_SQR ) { pAvoidObject = pEntity; flAvoidForce = 60.0f; break; } } pEntity = gEntList.NextEnt( pEntity ); } } if( pAvoidObject ) { // Build a force vector to push us away from the inhibitor. // Start by pushing upwards. Vector vecForce = Vector( 0, 0, VPhysicsGetObject()->GetMass() * 200.0f ); // Now add some force in the direction that takes us away from the inhibitor. Vector vecDir = GetAbsOrigin() - pAvoidObject->GetAbsOrigin(); vecDir.z = 0.0f; VectorNormalize( vecDir ); vecForce += vecDir * VPhysicsGetObject()->GetMass() * flAvoidForce; Flip( vecForce, AngularImpulse( 100, 0, 0 ) ); // Tell the code that asked that this position isn't valid. return false; } return true; }
//--------------------------------------------------------- // A different bounce behavior for the citizen-modified mine. Detonates at the top of its apex, // and does not attempt to track enemies. //--------------------------------------------------------- void CBounceBomb::CavernBounceThink() { SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance(); IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject != NULL ) { const float MINE_MAX_JUMP_HEIGHT = 78; // Figure out how much headroom the mine has, and hop to within a few inches of that. trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, MINE_MAX_JUMP_HEIGHT ), MASK_SHOT, this, COLLISION_GROUP_INTERACTIVE, &tr ); float height; if( tr.m_pEnt && tr.m_pEnt->VPhysicsGetObject() ) { // Physics object resting on me. Jump as hard as allowed to try to knock it away. height = MINE_MAX_JUMP_HEIGHT; } else { height = tr.endpos.z - GetAbsOrigin().z; height -= BOUNCEBOMB_RADIUS; if ( height < 0.1 ) height = 0.1; } float time = sqrt( height / (0.5 * sv_gravity.GetFloat()) ); float velocity = sv_gravity.GetFloat() * time; // or you can just AddVelocity to the object instead of ApplyForce float force = velocity * pPhysicsObject->GetMass(); Vector up; GetVectors( NULL, NULL, &up ); pPhysicsObject->Wake(); pPhysicsObject->ApplyForceCenter( up * force ); if( m_hNearestNPC ) { Vector vecPredict = m_hNearestNPC->GetSmoothedVelocity(); pPhysicsObject->ApplyForceCenter( vecPredict * (pPhysicsObject->GetMass() * 0.65f) ); } pPhysicsObject->ApplyTorqueCenter( AngularImpulse( random->RandomFloat( 15, 40 ), random->RandomFloat( 15, 40 ), random->RandomFloat( 30, 60 ) ) ); EmitSound( "NPC_CombineMine.Hop" ); SetThink( &CBounceBomb::ExplodeThink ); SetNextThink( gpGlobals->curtime + 0.33f ); } }
void CASW_Weapon_Freeze_Grenades::DelayedAttack( void ) { m_bShotDelayed = false; CASW_Player *pPlayer = GetCommander(); if ( !pPlayer ) return; CASW_Marine *pMarine = GetMarine(); if ( !pMarine || pMarine->GetWaterLevel() == 3 ) return; #ifndef CLIENT_DLL Vector vecSrc = pMarine->GetOffhandThrowSource(); Vector vecDest = pPlayer->GetCrosshairTracePos(); Vector newVel = UTIL_LaunchVector( vecSrc, vecDest, GetThrowGravity() ) * 28.0f; float fGrenadeRadius = GetBoomRadius( pMarine ); if (asw_debug_marine_damage.GetBool()) { Msg( "Freeze grenade radius = %f \n", fGrenadeRadius ); } pMarine->GetMarineSpeech()->Chatter( CHATTER_GRENADE ); // freeze aliens completely, plus the freeze duration float flFreezeAmount = 1.0f + MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_FREEZE_DURATION); if (ASWGameRules()) ASWGameRules()->m_fLastFireTime = gpGlobals->curtime; CASW_Grenade_Freeze *pGrenade = CASW_Grenade_Freeze::Freeze_Grenade_Create( 1.0f, flFreezeAmount, fGrenadeRadius, 0, vecSrc, pMarine->EyeAngles(), newVel, AngularImpulse(0,0,0), pMarine, this ); if ( pGrenade ) { pGrenade->SetGravity( GetThrowGravity() ); pGrenade->SetExplodeOnWorldContact( true ); } #endif // decrement ammo m_iClip1 -= 1; #ifndef CLIENT_DLL DestroyIfEmpty( true ); #endif m_flSoonestPrimaryAttack = gpGlobals->curtime + ASW_FLARES_FASTEST_REFIRE_TIME; if (m_iClip1 > 0) // only force the fire wait time if we have ammo for another shot m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); else m_flNextPrimaryAttack = gpGlobals->curtime; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer ) { Vector vecSrc = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); vecSrc += vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 ); Vector vecThrow = vForward * 350 + pPlayer->GetAbsVelocity() + Vector( 0, 0, 50 ); Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER ); // Play throw sound EmitSound( "WeaponFrag.Throw" ); m_bRedraw = true; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) { Vector vecSrc = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); vecSrc += vForward * 18.0f + vRight * 8.0f; // vForward[0] += 0.1f; vForward[2] += 0.1f; Vector vecThrow = vForward * 1200 + pPlayer->GetAbsVelocity(); Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER ); m_bRedraw = true; }
void CBaseSDKGrenade::ThrowGrenade() { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( !pPlayer ) { Assert( false ); return; } Vector vecSrc, vecThrow; QAngle angThrow; GetGrenadeThrowVectors(vecSrc, vecThrow, angThrow); EmitGrenade( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, this ); m_bRedraw = true; m_fThrowTime = 0.0f; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) { #ifndef CLIENT_DLL Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( pPlayer, vecEye, vecSrc ); // vForward[0] += 0.1f; vForward[2] += 0.1f; Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 1200; CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false ); if ( pGrenade ) { if ( pPlayer && pPlayer->m_lifeState != LIFE_ALIVE ) { pPlayer->GetVelocity( &vecThrow, NULL ); IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->SetVelocity( &vecThrow, NULL ); } } pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); } #endif m_bRedraw = true; WeaponSound( SINGLE ); // player "shoot" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); }
void CBaseSDKGrenade::DropGrenade() { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( !pPlayer ) { Assert( false ); return; } Vector vForward; pPlayer->EyeVectors( &vForward ); Vector vecSrc = pPlayer->GetAbsOrigin() + pPlayer->GetViewOffset() + vForward * 16; Vector vecVel = pPlayer->GetAbsVelocity(); EmitGrenade( vecSrc, vec3_angle, vecVel, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer ); m_bRedraw = true; m_fThrowTime = 0.0f; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer ) { Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 ); CheckThrowPosition( pPlayer, vecEye, vecSrc ); Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 350 + Vector( 0, 0, 50 ); Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER, false ); WeaponSound( WPN_DOUBLE ); m_bRedraw = true; m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); }
// This creates a vphysics object with a shadow controller that follows the AI IPhysicsObject *C_RagdollShadow::VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation ) { studiohdr_t *hdr = GetModelPtr(); if ( !hdr ) { return NULL; } // If this entity already has a physics object, then it should have been deleted prior to making this call. Assert(!m_pPhysicsObject); // make sure m_vecOrigin / m_vecAngles are correct const Vector &origin = GetAbsOrigin(); QAngle angles = GetAbsAngles(); IPhysicsObject *pPhysicsObject = NULL; if ( GetSolid() == SOLID_BBOX ) { const char *pSurfaceProps = "flesh"; if ( GetModelIndex() && modelinfo->GetModelType( GetModel() ) == mod_studio ) { pSurfaceProps = Studio_GetDefaultSurfaceProps( hdr ); } angles = vec3_angle; CPhysCollide *pCollide = PhysCreateBbox( WorldAlignMins(), WorldAlignMaxs() ); if ( !pCollide ) return NULL; pPhysicsObject = PhysModelCreateCustom( this, pCollide, origin, angles, pSurfaceProps ); } else { pPhysicsObject = PhysModelCreateRagdoll( this, GetModelIndex(), origin, angles ); } VPhysicsSetObject( pPhysicsObject ); pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), allowPhysicsMovement, allowPhysicsRotation ); pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); // PhysAddShadow( this ); return pPhysicsObject; }
void CBaseSDKGrenade::ThrowGrenade() { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( !pPlayer ) { Assert( false ); return; } QAngle angThrow = pPlayer->LocalEyeAngles(); Vector vForward, vRight, vUp; if (angThrow.x < 90 ) angThrow.x = -10 + angThrow.x * ((90 + 10) / 90.0); else { angThrow.x = 360.0f - angThrow.x; angThrow.x = -10 + angThrow.x * -((90 - 10) / 90.0); } float flVel = (90 - angThrow.x) * 8; if (flVel > 850) flVel = 850; AngleVectors( angThrow, &vForward, &vRight, &vUp ); Vector vecSrc = pPlayer->GetAbsOrigin() + pPlayer->GetViewOffset(); vecSrc += vForward * 16; Vector vecThrow = vForward * flVel + pPlayer->GetAbsVelocity(); EmitGrenade( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, this ); m_bRedraw = true; m_fThrowTime = 0.0f; }
void CBaseSDKGrenade::ThrowGrenade() { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( !pPlayer ) { Assert( false ); return; } Vector vecSrc = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); vecSrc += vForward * 18.0f + vRight * 8.0f; vForward[2] += 0.1f; Vector vecThrow = vForward * 1200 + pPlayer->GetAbsVelocity(); EmitGrenade( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, this ); m_bRedraw = true; m_fThrowTime = 0.0f; }
void CItem_ItemCrate::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ) { BaseClass::OnPhysGunPickup( pPhysGunUser, reason ); m_OnCacheInteraction.FireOutput( pPhysGunUser, this ); if ( reason == PUNTED_BY_CANNON && m_CrateAppearance != CRATE_APPEARANCE_RADAR_BEACON ) { Vector vForward; AngleVectors( pPhysGunUser->EyeAngles(), &vForward, NULL, NULL ); Vector vForce = Pickup_PhysGunLaunchVelocity( this, vForward, PHYSGUN_FORCE_PUNTED ); AngularImpulse angular = AngularImpulse( 0, 0, 0 ); IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) { pPhysics->AddVelocity( &vForce, &angular ); } TakeDamage( CTakeDamageInfo( pPhysGunUser, pPhysGunUser, GetHealth(), DMG_GENERIC ) ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer ) { // VR Source - if weapon tracking through based on weapon angle vector. Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( pPlayer, vecEye, vecSrc ); vForward[2] += 0.1f; Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); // VR Source - use weapon angle vectors if available if ( pPlayer->Weapon_Tracking() ) { vecThrow += pPlayer->Weapon_ShootDirection() * 1200; } else { vecThrow += vForward * 1200; } //todo: do I need to replace the vec3_angle as well? Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false ); m_bRedraw = true; WeaponSound( SINGLE ); m_iPrimaryAttacks++; gamestats->Event_WeaponFired( pPlayer, true, GetClassname() ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponHopwire::LobGrenade( CBasePlayer *pPlayer ) { Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 ); CheckThrowPosition( pPlayer, vecEye, vecSrc ); Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 350 + Vector( 0, 0, 50 ); m_hActiveHopWire = static_cast<CGrenadeHopwire *> (HopWire_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER )); WeaponSound( WPN_DOUBLE ); m_bRedraw = true; }
/// @TODO: lead target void CASW_Sentry_Top_Cannon::Fire() { if ( !m_hEnemy.IsValid() || !m_hEnemy.Get() || !HasAmmo() ) return; BaseClass::Fire(); Vector diff = m_hEnemy->WorldSpaceCenter() - GetFiringPosition(); diff.NormalizeInPlace(); //FireBulletsInfo_t( int nShots, const Vector &vecSrc, const Vector &vecDir, const Vector &vecSpread, float flDistance, int nAmmoType, bool bPrimaryAttack = true ) Vector launchVector = diff * 1000.0f; CASW_Marine * RESTRICT pMarineDeployer = GetSentryBase()->m_hDeployer.Get(); Assert( pMarineDeployer ); float fGrenadeDamage = CASW_Weapon_Grenades::GetBoomDamage(pMarineDeployer) * 0.5f; float fGrenadeRadius = CASW_Weapon_Grenades::GetBoomRadius(pMarineDeployer) * 0.5f; CASW_Rifle_Grenade::Rifle_Grenade_Create( fGrenadeDamage, fGrenadeRadius, GetFiringPosition() + (diff * ( WorldAlignSize().Length() * 0.5f ) ), GetAbsAngles(), launchVector, AngularImpulse(0,0,0), pMarineDeployer, this ); if( pMarineDeployer ) pMarineDeployer->OnWeaponFired( this, 1 ); EmitSound("ASW_Sentry.CannonFire"); m_fNextFireTime = gpGlobals->curtime + ASW_SENTRY_CANNON_FIRE_RATE; // use ammo if ( GetSentryBase() ) { GetSentryBase()->OnFiredShots(); } }
void CASW_Weapon_Assault_Shotgun::SecondaryAttack() { // Only the player fires this way so we can cast CASW_Player *pPlayer = GetCommander(); if (!pPlayer) return; CASW_Marine *pMarine = GetMarine(); if (!pMarine) return; //Must have ammo bool bUsesSecondary = UsesSecondaryAmmo(); bool bUsesClips = UsesClipsForAmmo2(); int iAmmoCount = pMarine->GetAmmoCount(m_iSecondaryAmmoType); bool bInWater = ( pMarine->GetWaterLevel() == 3 ); if ( (bUsesSecondary && ( ( bUsesClips && m_iClip2 <= 0) || ( !bUsesClips && iAmmoCount<=0 ) ) ) || bInWater || m_bInReload ) { SendWeaponAnim( ACT_VM_DRYFIRE ); BaseClass::WeaponSound( EMPTY ); m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f; return; } BaseClass::WeaponSound( SPECIAL1 ); #ifndef CLIENT_DLL pMarine->GetMarineSpeech()->Chatter(CHATTER_GRENADE); Vector vecSrc = pMarine->Weapon_ShootPosition(); Vector vecThrow; // check for turning on lag compensation if (pPlayer && pMarine->IsInhabited()) { CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() ); } vecThrow = UTIL_LaunchVector(vecSrc, pPlayer->GetCrosshairTracePos(), asw_vindicator_grenade_gravity.GetFloat()) * 8.0f * asw_vindicator_grenade_velocity.GetFloat(); QAngle angAiming = pPlayer->EyeAnglesWithCursorRoll(); float fGrenadeDamage = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_INCENDIARY_DMG); float fGrenadeRadius = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_RADIUS); if (asw_debug_marine_damage.GetBool()) { Msg("Grenade damage = %f radius = %f\n", fGrenadeDamage, fGrenadeRadius); } // check the grenade fits where we want to spawn it Ray_t ray; trace_t pm; ray.Init( pMarine->WorldSpaceCenter(), vecSrc, -Vector(4,4,4), Vector(4,4,4) ); UTIL_TraceRay( ray, MASK_SOLID, pMarine, COLLISION_GROUP_PROJECTILE, &pm ); if (pm.fraction < 1.0f) vecSrc = pm.endpos; CASW_Grenade_Vindicator::Vindicator_Grenade_Create( fGrenadeDamage, fGrenadeRadius, vecSrc, angAiming, vecThrow, AngularImpulse(0,0,0), pMarine, this ); pMarine->OnWeaponFired( this, 1, true ); #endif SendWeaponAnim( GetPrimaryAttackActivity() ); pMarine->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN_PRIMARY ); // Decrease ammo if ( bUsesClips ) { m_iClip2 -= 1; } else { pMarine->RemoveAmmo( 1, m_iSecondaryAmmoType ); } #ifndef CLIENT_DLL ASWFailAdvice()->OnMarineUsedSecondary(); CEffectData data; data.m_vOrigin = GetAbsOrigin(); //data.m_vNormal = dir; //data.m_flScale = (float)amount; CPASFilter filter( data.m_vOrigin ); filter.SetIgnorePredictionCull(true); DispatchParticleEffect( "muzzleflash_grenadelauncher_main", PATTACH_POINT_FOLLOW, this, "muzzle", false, -1, &filter ); #endif // Can shoot again immediately m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f; // Can blow up after a short delay (so have time to release mouse button) m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f; }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); // keep track of think time deltas for burn calc below float dt = gpGlobals->curtime - m_flLastTime; m_flLastTime = gpGlobals->curtime; switch( m_iLandState ) { case LANDING_NO: { if ( IsActivityFinished() && (GetActivity() != ACT_DROPSHIP_FLY_IDLE_EXAGG && GetActivity() != ACT_DROPSHIP_FLY_IDLE_CARGO) ) { if ( m_hContainer ) { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO ); } else { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG ); } } DoRotorWash(); } break; case LANDING_LEVEL_OUT: { // Approach the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // If we're slowing, make it look like we're slowing /* if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } */ // Are we there yet? float flSpeed = GetAbsVelocity().Length(); if ( flDistance < 70 && flSpeed < 100 ) { m_flLandingSpeed = flSpeed; m_iLandState = LANDING_DESCEND; // save off current angles so we can work them out over time QAngle angles = GetLocalAngles(); m_existPitch = angles.x; m_existRoll = angles.z; } DoRotorWash(); } break; case LANDING_DESCEND: { float flAltitude; SetLocalAngularVelocity( vec3_angle ); // Ensure we land on the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); float flRampedSpeed = m_flLandingSpeed * (flDistance / 70); Vector vecVelocity = (flRampedSpeed / flDistance) * vecToTarget; vecVelocity.z = -75; SetAbsVelocity( vecVelocity ); flAltitude = GetAltitude(); if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } if ( flAltitude < 72 ) { QAngle angles = GetLocalAngles(); // Level out quickly. angles.x = UTIL_Approach( 0.0, angles.x, 0.2 ); angles.z = UTIL_Approach( 0.0, angles.z, 0.2 ); SetLocalAngles( angles ); } else { // randomly move as if buffeted by ground effects // gently flatten ship from starting pitch/yaw m_existPitch = UTIL_Approach( 0.0, m_existPitch, 1 ); m_existRoll = UTIL_Approach( 0.0, m_existRoll, 1 ); QAngle angles = GetLocalAngles(); angles.x = m_existPitch + ( sin( gpGlobals->curtime * 3.5f ) * DROPSHIP_MAX_LAND_TILT ); angles.z = m_existRoll + ( sin( gpGlobals->curtime * 3.75f ) * DROPSHIP_MAX_LAND_TILT ); SetLocalAngles( angles ); // figure out where to face (nav point) Vector targetDir = GetDesiredPosition() - GetAbsOrigin(); // NDebugOverlay::Cross3D( m_pGoalEnt->GetAbsOrigin(), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 20 ); QAngle targetAngles = GetAbsAngles(); targetAngles.y += UTIL_AngleDiff(UTIL_VecToYaw( targetDir ), targetAngles.y); // orient ship towards path corner on the way down angles = GetAbsAngles(); angles.y = UTIL_Approach(targetAngles.y, angles.y, 2 ); SetAbsAngles( angles ); } if ( flAltitude <= 0.5f ) { m_iLandState = LANDING_TOUCHDOWN; // upon landing, make sure ship is flat QAngle angles = GetLocalAngles(); angles.x = 0; angles.z = 0; SetLocalAngles( angles ); // TODO: Release cargo anim SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } DoRotorWash(); // place danger sounds 1 foot above ground to get troops to scatter if they are below dropship Vector vecBottom = GetAbsOrigin(); vecBottom.z += WorldAlignMins().z; Vector vecSpot = vecBottom + Vector(0, 0, -1) * (GetAltitude() - 12 ); CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.2, this, 0 ); CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.2, this, 1 ); // NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f ); // now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move) trace_t tr; Vector vecBBoxMin = CRATE_BBOX_MIN; // use flat box for check vecBBoxMin.z = -5; Vector vecBBoxMax = CRATE_BBOX_MAX; vecBBoxMax.z = 5; Vector pEndPoint = vecBottom + Vector(0, 0, -1) * ( GetAltitude() - 12 ); AI_TraceHull( vecBottom, pEndPoint, vecBBoxMin, vecBBoxMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { if ( tr.GetEntityIndex() == 1 ) // player??? { CTakeDamageInfo info( this, this, 20 * dt, DMG_BURN ); CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); pPlayer->TakeDamage( info ); } } } break; case LANDING_TOUCHDOWN: { if ( IsActivityFinished() && ( GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } m_iLandState = LANDING_UNLOADING; m_flTroopDeployPause = gpGlobals->curtime + DROPSHIP_PAUSE_B4_TROOP_UNLOAD; m_flTimeTakeOff = m_flTroopDeployPause + DROPSHIP_DEPLOY_TIME; } break; case LANDING_UNLOADING: { // pause before dropping troops if ( gpGlobals->curtime > m_flTroopDeployPause ) { if ( m_hContainer ) // don't drop troops if we don't have a crate any more { SpawnTroops(); m_flTroopDeployPause = m_flTimeTakeOff + 2; // only drop once } } // manage engine wash and volume if ( m_flTimeTakeOff - gpGlobals->curtime < 0.5f ) { m_engineThrust = UTIL_Approach( 1.0f, m_engineThrust, 0.1f ); DoRotorWash(); } else { float idleVolume = 0.2f; m_engineThrust = UTIL_Approach( idleVolume, m_engineThrust, 0.04f ); if ( m_engineThrust > idleVolume ) { DoRotorWash(); // make sure we're kicking up dust/water as long as engine thrust is up } } if( gpGlobals->curtime > m_flTimeTakeOff ) { m_iLandState = LANDING_LIFTOFF; SetActivity( (Activity)ACT_DROPSHIP_LIFTOFF ); m_engineThrust = 1.0f; // ensure max volume once we're airborne if ( m_bIsFiring ) { StopCannon(); // kill cannon sounds if they are on } // detach container from ship if ( m_hContainer && m_leaveCrate ) { m_hContainer->SetParent(NULL); m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType ); // If the container has a physics object, remove it's shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->RemoveShadowController(); } m_hContainer = NULL; } } } break; case LANDING_LIFTOFF: { // give us some clearance before changing back to larger hull -- keeps ship from getting stuck on // things like the player, etc since we "pop" the hull... if ( GetAltitude() > 120 ) { m_OnFinishedDropoff.FireOutput( this, this ); m_iLandState = LANDING_NO; // change bounding box back to normal ship hull Vector vecBBMin, vecBBMax; ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), vecBBMin, vecBBMax ); UTIL_SetSize( this, vecBBMin, vecBBMax ); Relink(); } } break; case LANDING_SWOOPING: { // Did we lose our pickup target? if ( !m_hPickupTarget ) { m_iLandState = LANDING_NO; } else { // Decrease altitude and speed to hit the target point. Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // Start cheating when we get near it if ( flDistance < 50 ) { /* if ( flDistance > 10 ) { // Cheat and ensure we touch the target float flSpeed = GetAbsVelocity().Length(); Vector vecVelocity = vecToTarget; VectorNormalize( vecVelocity ); SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) ); } else */ { // Grab the target m_hContainer = m_hPickupTarget; m_hPickupTarget = NULL; m_iContainerMoveType = m_hContainer->GetMoveType(); // If the container has a physics object, move it to shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), false, false ); pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); } int iIndex = 0;//LookupAttachment("Cargo"); /* Vector vecOrigin; QAngle vecAngles; GetAttachment( iIndex, vecOrigin, vecAngles ); m_hContainer->SetAbsOrigin( vecOrigin ); m_hContainer->SetAbsAngles( vec3_angle ); */ m_hContainer->SetAbsOrigin( GetAbsOrigin() ); m_hContainer->SetParent(this, iIndex); m_hContainer->SetMoveType( MOVETYPE_PUSH ); m_hContainer->RemoveFlag( FL_ONGROUND ); m_hContainer->Relink(); m_hContainer->SetAbsAngles( vec3_angle ); m_OnFinishedPickup.FireOutput( this, this ); m_iLandState = LANDING_NO; } } } DoRotorWash(); } break; } DoCombatStuff(); if ( GetActivity() != GetIdealActivity() ) { //Msg( "setactivity" ); SetActivity( GetIdealActivity() ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer, bool Invis /*= false*/ ) { #ifndef CLIENT_DLL Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( pPlayer, vecEye, vecSrc ); // vForward[0] += 0.1f; vForward[2] += 0.1f; Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); //DHL - We're just gonna set the grenade off at vecSrc if it goes off "in their hand", so don't worry about velocity if ( !Invis ) vecThrow += vForward * 1200; //DHL: Added conditional to last arg, to allow priming... //If we haven't hit the time we should explode yet, use the remaining time as the clock for the grenade //Otherwise (we're due to explode) throw (will be forced in the PostFrame function) and go off near immediately CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, ( (flExplodeTime > gpGlobals->curtime) ? (flExplodeTime - gpGlobals->curtime) : 0.01f ), false ); if ( pGrenade ) { if ( pPlayer && pPlayer->m_lifeState != LIFE_ALIVE ) { pPlayer->GetVelocity( &vecThrow, NULL ); IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->SetVelocity( &vecThrow, NULL ); } } pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage ); pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS ); if ( Invis ) //DHL - Don't always want to be able to see the grenade { pGrenade->AddEffects( EF_NODRAW ); pGrenade->SetMoveType( MOVETYPE_NONE ); CUtlVector<CBaseEntity *> childrenList; GetAllChildren( pGrenade, childrenList ); if ( childrenList.Count() ) // If there's any children in the list... { for ( int i = childrenList.Count()-1; i >= 0; --i ) { UTIL_Remove( childrenList[i] ); //Remove them all } } pGrenade->SetAbsVelocity( vec3_origin ); pGrenade->SetAbsOrigin( vecSrc ); //Put the grenade right back in their hand incase it's moved pGrenade->Detonate(); } } #endif m_bRedraw = true; WeaponSound( SINGLE ); // player "shoot" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); }
void CNPC_Zombine::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == AE_ZOMBINE_PULLPIN ) { Vector vecStart; QAngle angles; GetAttachment( "grenade_attachment", vecStart, angles ); CBaseGrenade *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vec3_origin, AngularImpulse( 0, 0, 0 ), this, 3.5f, true ); if ( pGrenade ) { // Move physobject to shadow IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject(); if ( pPhysicsObject ) { pGrenade->VPhysicsDestroyObject(); int iAttachment = LookupAttachment( "grenade_attachment"); pGrenade->SetMoveType( MOVETYPE_NONE ); pGrenade->SetSolid( SOLID_NONE ); pGrenade->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); pGrenade->SetAbsOrigin( vecStart ); pGrenade->SetAbsAngles( angles ); pGrenade->SetParent( this, iAttachment ); pGrenade->SetDamage( 200.0f ); m_hGrenade = pGrenade; EmitSound( "Zombine.ReadyGrenade" ); // Tell player allies nearby to regard me! CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); CAI_BaseNPC *pNPC; for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ ) { pNPC = ppAIs[i]; if( pNPC->Classify() == CLASS_PLAYER_ALLY || pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) ) { int priority; Disposition_t disposition; priority = pNPC->IRelationPriority(this); disposition = pNPC->IRelationType(this); pNPC->AddEntityRelationship( this, disposition, priority + 1 ); } } } m_iGrenadeCount--; } return; } if ( pEvent->event == AE_NPC_ATTACK_BROADCAST ) { if ( HasGrenade() ) return; } BaseClass::HandleAnimEvent( pEvent ); }
//----------------------------------------------------------------------------- // Purpose: Throw a primed grenade with timeleft of (gpGlobals->curtime - m_flPrimedTime) //----------------------------------------------------------------------------- void CGEWeaponGrenade::ThrowGrenade( float throwforce ) { CBaseCombatCharacter *pOwner = GetOwner(); if ( !pOwner ) return; // Remove the grenade from our ammo pool pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType ); #ifndef CLIENT_DLL Vector vecEye = pOwner->EyePosition(); Vector vForward, vRight; AngleVectors( pOwner->EyeAngles(), &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( vecEye, vecSrc ); vForward[2] += 0.1f; Vector vecThrow; pOwner->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * throwforce; // Convert us into a bot player :-D if ( pOwner->IsNPC() ) { CNPC_GEBase *pNPC = (CNPC_GEBase*) pOwner; if ( pNPC->GetBotPlayer() ) pOwner = pNPC->GetBotPlayer(); } CGEGrenade *pGrenade = (CGEGrenade *)CBaseEntity::Create( "npc_grenade", vecSrc, vec3_angle, NULL ); if ( pGrenade ) { pGrenade->SetThrower( pOwner ); pGrenade->SetOwnerEntity( pOwner ); pGrenade->SetVelocity( vecThrow, AngularImpulse(600,random->RandomInt(-1000,1000),0) ); pGrenade->SetDamage( GetGEWpnData().m_iDamage ); pGrenade->SetDamageRadius( GetGEWpnData().m_flDamageRadius ); pGrenade->SetSourceWeapon(this); if (throwforce == GE_GRENADE_THROW_FORCE / 5) // For acheivement tracking. pGrenade->m_bDroppedOnDeath = true; // The timer is whatever is left over from the primed time + our fuse minus our // current time to give us an absolute time in seconds pGrenade->SetTimer( (m_flPrimedTime + GE_GRENADE_FUSE_TIME) - gpGlobals->curtime ); // Tell the owner what we threw to implement anti-spamming if ( pOwner->IsPlayer() ) ToGEMPPlayer(pOwner)->AddThrownObject( pGrenade ); } #endif m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_flTimeWeaponIdle = gpGlobals->curtime + GE_GRENADE_IDLE_DELAY; m_bDrawNext = true; WeaponSound( SINGLE ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::SettleThink() { SetNextThink( gpGlobals->curtime + 0.05 ); StudioFrameAdvance(); if( GetParent() ) { // A scanner or something is carrying me. Just keep checking back. return; } // Not being carried. if( !VPhysicsGetObject() ) { // Probably was just dropped. Get physics going. CreateVPhysics(); if( !VPhysicsGetObject() ) { Msg("**** Can't create vphysics for combine_mine!\n" ); UTIL_Remove( this ); return; } VPhysicsGetObject()->Wake(); return; } if( !m_bDisarmed ) { if( VPhysicsGetObject()->IsAsleep() && !(VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) ) { // If i'm not resting on the world, jump randomly. trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1024 ), MASK_SHOT|CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &tr ); bool bHop = false; if( tr.m_pEnt ) { IPhysicsObject *pPhysics = tr.m_pEnt->VPhysicsGetObject(); if( pPhysics && pPhysics->GetMass() <= 1000 ) { // Light physics objects can be moved out from under the mine. bHop = true; } else if( tr.m_pEnt->m_takedamage != DAMAGE_NO ) { // Things that can be harmed can likely be broken. bHop = true; } if( bHop ) { Vector vecForce; vecForce.x = random->RandomFloat( -1000, 1000 ); vecForce.y = random->RandomFloat( -1000, 1000 ); vecForce.z = 2500; AngularImpulse torque( 160, 0, 160 ); Flip( vecForce, torque ); return; } // Check for upside-down Vector vecUp; GetVectors( NULL, NULL, &vecUp ); if( vecUp.z <= 0.8 ) { // Landed upside down. Right self Vector vecForce( 0, 0, 2500 ); Flip( vecForce, AngularImpulse( 60, 0, 0 ) ); return; } } // Check to make sure I'm not in a forbidden location if( !IsValidLocation() ) { return; } // Lock to what I'm resting on constraint_ballsocketparams_t ballsocket; ballsocket.Defaults(); ballsocket.constraint.Defaults(); ballsocket.constraint.forceLimit = lbs2kg(1000); ballsocket.constraint.torqueLimit = lbs2kg(1000); ballsocket.InitWithCurrentObjectState( g_PhysWorldObject, VPhysicsGetObject(), GetAbsOrigin() ); m_pConstraint = physenv->CreateBallsocketConstraint( g_PhysWorldObject, VPhysicsGetObject(), NULL, ballsocket ); CloseHooks(); SetMineState( MINE_STATE_ARMED ); } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - //----------------------------------------------------------------------------- void CWeaponHopwire::ThrowGrenade( CBasePlayer *pPlayer ) { Vector vecEye = pPlayer->EyePosition(); Vector vForward, vRight; pPlayer->EyeVectors( &vForward, &vRight, NULL ); Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; CheckThrowPosition( pPlayer, vecEye, vecSrc ); vForward[2] += 0.1f; Vector vecThrow; pPlayer->GetVelocity( &vecThrow, NULL ); vecThrow += vForward * 1200; m_hActiveHopWire = static_cast<CGrenadeHopwire *> (HopWire_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER )); m_bRedraw = true; WeaponSound( SINGLE ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::SetMineState( int iState ) { m_iMineState = iState; switch( iState ) { case MINE_STATE_DORMANT: { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.1 ); UpdateLight( false, 0, 0, 0, 0 ); SetThink( NULL ); } break; case MINE_STATE_CAPTIVE: { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.2 ); // Unhook unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); VPhysicsGetObject()->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC ); OpenHooks(); physenv->DestroyConstraint( m_pConstraint ); m_pConstraint = NULL; UpdateLight( true, 0, 0, 255, 190 ); SetThink( &CBounceBomb::CaptiveThink ); SetNextThink( gpGlobals->curtime + 0.1f ); SetTouch( NULL ); } break; case MINE_STATE_DEPLOY: OpenHooks( true ); UpdateLight( true, 0, 0, 255, 190 ); SetThink( &CBounceBomb::SettleThink ); SetTouch( NULL ); SetNextThink( gpGlobals->curtime + 0.1f ); break; case MINE_STATE_ARMED: UpdateLight( false, 0, 0, 0, 0 ); SetThink( &CBounceBomb::SearchThink ); SetNextThink( gpGlobals->curtime + 0.1f ); break; case MINE_STATE_TRIGGERED: { OpenHooks(); if( m_pConstraint ) { physenv->DestroyConstraint( m_pConstraint ); m_pConstraint = NULL; } // Scare NPC's CSoundEnt::InsertSound( SOUND_DANGER, GetAbsOrigin(), 300, 1.0f, this ); CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundChangeVolume( m_pWarnSound, 0.0, 0.2 ); SetTouch( &CBounceBomb::ExplodeTouch ); unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); VPhysicsGetObject()->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC ); Vector vecNudge; vecNudge.x = random->RandomFloat( -1, 1 ); vecNudge.y = random->RandomFloat( -1, 1 ); vecNudge.z = 1.5; vecNudge *= 350; VPhysicsGetObject()->Wake(); VPhysicsGetObject()->ApplyForceCenter( vecNudge ); float x, y; x = 10 + random->RandomFloat( 0, 20 ); y = 10 + random->RandomFloat( 0, 20 ); VPhysicsGetObject()->ApplyTorqueCenter( AngularImpulse( x, y, 0 ) ); // Since we just nudged the mine, ignore collisions with the world until // the mine is in the air. We only want to explode if the player tries to // run over the mine before it jumps up. m_flIgnoreWorldTime = gpGlobals->curtime + 1.0; UpdateLight( true, 255, 0, 0, 190 ); // use the correct bounce behavior if (m_iModification == MINE_MODIFICATION_CAVERN) { SetThink ( &CBounceBomb::CavernBounceThink ); SetNextThink( gpGlobals->curtime + 0.15 ); } else { SetThink( &CBounceBomb::BounceThink ); SetNextThink( gpGlobals->curtime + 0.5 ); } } break; case MINE_STATE_LAUNCHED: { UpdateLight( true, 255, 0, 0, 190 ); SetThink( NULL ); SetNextThink( gpGlobals->curtime + 0.5 ); SetTouch( &CBounceBomb::ExplodeTouch ); unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); VPhysicsGetObject()->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC ); } break; default: DevMsg("**Unknown Mine State: %d\n", iState ); break; } }