void CBaseGrenadeProjectile::SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity ) { IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity( &velocity, &angVelocity ); } }
void CTripwireHook::SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity ) { IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity( &velocity, &angVelocity ); } }
//DHL - Skillet - Fix ammo exploits void CWeaponFrag::Drop( const Vector &vecVelocity ) { if ( !HasPrimaryAmmo() ) { //BaseClass::Drop( vecVelocity ); SUB_Remove(); return; } if ( !GetOwner() ) return; DecrementAmmo( GetOwner() ); Reload(); //Do draw animation and stuff #ifndef CLIENT_DLL CBasePlayer *owner = ToBasePlayer(GetOwner()); Vector vThrowPos = owner->Weapon_ShootPosition() - Vector(0,0,12); //Create a grenade CBaseCombatWeapon* pGrenade; pGrenade = (CBaseCombatWeapon *)CBaseEntity::Create( "weapon_frag", vThrowPos, vec3_angle, NULL ); if ( !pGrenade ) return; pGrenade->SetRemoveable( true ); //If it was dropped then there's no need to respawn it. pGrenade->AddSpawnFlags( SF_NORESPAWN ); pGrenade->StopAnimation(); pGrenade->StopFollowingEntity( ); pGrenade->SetMoveType( MOVETYPE_FLYGRAVITY ); // clear follow stuff, setup for collision pGrenade->SetGravity(1.0); pGrenade->m_iState = WEAPON_NOT_CARRIED; pGrenade->RemoveEffects( EF_NODRAW ); pGrenade->FallInit(); pGrenade->SetGroundEntity( NULL ); pGrenade->SetTouch(NULL); pGrenade->SetOwnerEntity( NULL ); pGrenade->SetOwner( NULL ); //Toss it in the direction of the player's view Vector vecNewVelocity; Vector vecDir; owner->EyeVectors( &vecDir ); vecNewVelocity = ( vecDir * 500.0f ); IPhysicsObject *pObj = pGrenade->VPhysicsGetObject(); if ( pObj != NULL ) { AngularImpulse angImp( 200, 200, 200 ); pObj->AddVelocity( &vecNewVelocity, &angImp ); } #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGrenadeHopwire::SetVelocity( const Vector &velocity, const AngularImpulse &angVelocity ) { IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject != NULL ) { pPhysicsObject->AddVelocity( &velocity, &angVelocity ); } }
//------------------------------------------------------------------------------ // Purpose : Initialize a gibs position and velocity // Input : // Output : //------------------------------------------------------------------------------ void CGib::InitGib( CBaseEntity *pVictim, float fMinVelocity, float fMaxVelocity ) { // ------------------------------------------------------------------------ // If have a pVictim spawn the gib somewhere in the pVictim's bounding volume // ------------------------------------------------------------------------ if ( pVictim ) { // Find a random position within the bounding box (add 1 to Z to get it out of the ground) Vector vecOrigin; pVictim->CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &vecOrigin ); vecOrigin.z += 1.0f; SetAbsOrigin( vecOrigin ); // make the gib fly away from the attack vector Vector vecNewVelocity = g_vecAttackDir * -1; // mix in some noise vecNewVelocity.x += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.y += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.z += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity *= random->RandomFloat ( fMaxVelocity, fMinVelocity ); QAngle vecNewAngularVelocity = GetLocalAngularVelocity(); vecNewAngularVelocity.x = random->RandomFloat ( 100, 200 ); vecNewAngularVelocity.y = random->RandomFloat ( 100, 300 ); SetLocalAngularVelocity( vecNewAngularVelocity ); // copy owner's blood color SetBloodColor( pVictim->BloodColor() ); AdjustVelocityBasedOnHealth( pVictim->m_iHealth, vecNewVelocity ); // Attempt to be physical if we can if ( VPhysicsInitNormal( SOLID_BBOX, 0, false ) ) { IPhysicsObject *pObj = VPhysicsGetObject(); if ( pObj != NULL ) { AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); pObj->AddVelocity( &vecNewVelocity, &angImpulse ); } } else { SetSolid( SOLID_BBOX ); SetCollisionBounds( vec3_origin, vec3_origin ); SetAbsVelocity( vecNewVelocity ); } SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } LimitVelocity(); }
void C_PhysPropClientside::Clone( Vector &velocity ) { C_PhysPropClientside *pEntity = C_PhysPropClientside::CreateNew(); if ( !pEntity ) return; pEntity->m_spawnflags = m_spawnflags; // We never want to be motion disabled pEntity->m_spawnflags &= ~SF_PHYSPROP_MOTIONDISABLED; pEntity->SetDmgModBullet( GetDmgModBullet() ); pEntity->SetDmgModClub( GetDmgModClub() ); pEntity->SetDmgModExplosive( GetDmgModExplosive() ); pEntity->SetModelName( GetModelName() ); pEntity->SetLocalOrigin( GetLocalOrigin() ); pEntity->SetLocalAngles( GetLocalAngles() ); pEntity->SetOwnerEntity( this ); pEntity->SetPhysicsMode( PHYSICS_MULTIPLAYER_CLIENTSIDE ); if ( !pEntity->Initialize() ) { pEntity->Release(); return; } pEntity->m_nSkin = m_nSkin; pEntity->m_iHealth = m_iHealth; if ( pEntity->m_iHealth == 0 ) { // if no health, don't collide with player anymore, don't take damage pEntity->m_takedamage = DAMAGE_NO; pEntity->SetCollisionGroup( COLLISION_GROUP_NONE ); } IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if( pPhysicsObject ) { // randomize velocity by 5% float rndf = RandomFloat( -0.025, 0.025 ); Vector rndVel = velocity + rndf*velocity; pPhysicsObject->AddVelocity( &rndVel, NULL ); } else { // failed to create a physics object pEntity->Release(); } }
//----------------------------------------------------------------------------- // Create a corpse //----------------------------------------------------------------------------- void CPropAPC::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < APC_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); if ( flMass < 200 ) { Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } if( hl2_episodic.GetBool() ) { // EP1 perf hit pGib->Ignite( 6, false ); } else { pGib->Ignite( 60, false ); } } AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_Remove( this ); }
void QUA_helicopter::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < HELICOPTER_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics_multiplayer" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); /*if ( flMass < 200 ) {*/ Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); /*}*/ pGib->Ignite( 60, false ); pGib->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_RemoveImmediate( this ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPhysMagnet::DoMagnetSuck( CBaseEntity *pOther ) { if ( !HasSpawnFlags( SF_MAGNET_SUCK ) ) return; if ( !m_bActive ) return; // Don't repeatedly suck if ( m_flNextSuckTime > gpGlobals->curtime ) return; // Look for physics objects underneath the magnet and suck them onto it Vector vecCheckPos, vecSuckPoint; VectorTransform( Vector(0,0,-96), EntityToWorldTransform(), vecCheckPos ); VectorTransform( Vector(0,0,-64), EntityToWorldTransform(), vecSuckPoint ); CBaseEntity *pEntities[20]; int iNumEntities = UTIL_EntitiesInSphere( pEntities, 20, vecCheckPos, 80.0, 0 ); for ( int i = 0; i < iNumEntities; i++ ) { CBaseEntity *pEntity = pEntities[i]; if ( !pEntity || pEntity == pOther ) continue; IPhysicsObject *pPhys = pEntity->VPhysicsGetObject(); if ( pPhys && pEntity->GetMoveType() == MOVETYPE_VPHYSICS && pPhys->GetMass() < 5000 ) { // Do we have line of sight to it? trace_t tr; UTIL_TraceLine( GetAbsOrigin(), pEntity->GetAbsOrigin(), MASK_SHOT, this, 0, &tr ); if ( tr.fraction == 1.0 || tr.m_pEnt == pEntity ) { // Pull it towards the magnet Vector vecVelocity = (vecSuckPoint - pEntity->GetAbsOrigin()); VectorNormalize(vecVelocity); vecVelocity *= 5 * pPhys->GetMass(); pPhys->AddVelocity( &vecVelocity, NULL ); } } } m_flNextSuckTime = gpGlobals->curtime + 2.0; }
void C_StriderRagdoll::OnDataChanged( DataUpdateType_t type ) { BaseClass::OnDataChanged( type ); if ( type == DATA_UPDATE_CREATED ) { CreateStriderRagdoll(); IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if( pPhysicsObject ) { AngularImpulse aVelocity(0,0,0); Vector vecExaggeratedVelocity = 3 * m_vecRagdollVelocity; pPhysicsObject->AddVelocity( &vecExaggeratedVelocity, &aVelocity ); } } }
//----------------------------------------------------------------------------- // Purpose: // // //----------------------------------------------------------------------------- void CWeaponBrickbat::ThrowBrickbat( Vector vecSrc, Vector vecVelocity, float damage) { CGrenade_Brickbat *pBrickbat = (CGrenade_Brickbat*)Create( BrickBatAmmoArray[m_iCurrentAmmoType].m_sClassName, vecSrc, vec3_angle, GetOwner() ); if (!pBrickbat) { Msg("Brickbat type (%s) not defined!\n",BrickBatAmmoArray[m_iCurrentAmmoType].m_sClassName); return; } AngularImpulse vecAngVel; // Tumble through the air vecAngVel.x = random->RandomFloat ( -100, -500 ); vecAngVel.z = random->RandomFloat ( -100, -500 ); vecAngVel.y = random->RandomFloat ( -100, -500 ); // If physically simulated IPhysicsObject *pPhysicsObject = pBrickbat->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity( &vecVelocity, &vecAngVel ); } // Otherwise else { pBrickbat->SetAbsVelocity( vecVelocity ); QAngle angVel; AngularImpulseToQAngle( vecAngVel, angVel ); pBrickbat->SetLocalAngularVelocity( angVel ); } pBrickbat->SetThrower( GetOwner() ); pBrickbat->SetOwnerEntity( ((CBaseEntity*)GetOwner()) ); pBrickbat->SetDamage(damage); m_nAmmoCount[m_iCurrentAmmoType]--; m_bNeedThrow = false; }
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: //----------------------------------------------------------------------------- void CTFWeaponBaseGrenadeProj::InitGrenade( const Vector &velocity, const AngularImpulse &angVelocity, CBaseCombatCharacter *pOwner, const CTFWeaponInfo &weaponInfo ) { // We can't use OwnerEntity for grenades, because then the owner can't shoot them with his hitscan weapons (due to collide rules) // Thrower is used to store the person who threw the grenade, for damage purposes. SetOwnerEntity( NULL ); SetThrower( pOwner ); SetupInitialTransmittedGrenadeVelocity( velocity ); SetGravity( 0.4f/*BaseClass::GetGrenadeGravity()*/ ); SetFriction( 0.2f/*BaseClass::GetGrenadeFriction()*/ ); SetElasticity( 0.45f/*BaseClass::GetGrenadeElasticity()*/ ); SetDamage( weaponInfo.GetWeaponData( TF_WEAPON_PRIMARY_MODE ).m_nDamage ); SetDamageRadius( weaponInfo.m_flDamageRadius ); ChangeTeam( pOwner->GetTeamNumber() ); IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity( &velocity, &angVelocity ); } }
void CNPC_Portal_FloorTurret::StartTouch( CBaseEntity *pOther ) { BaseClass::StartTouch( pOther ); IPhysicsObject *pOtherPhys = pOther->VPhysicsGetObject(); if ( !pOtherPhys ) return; if ( !m_pMotionController ) return; if ( m_pMotionController->Enabled() ) { m_pMotionController->Suspend( 2.0f ); IPhysicsObject *pTurretPhys = VPhysicsGetObject(); if ( !pOther->IsPlayer() && pOther->GetMoveType() == MOVETYPE_VPHYSICS && !(pTurretPhys && ((pTurretPhys->GetGameFlags() & FVPHYSICS_PLAYER_HELD) != 0)) ) { // Get a lateral impulse Vector vVelocityImpulse = GetAbsOrigin() - pOther->GetAbsOrigin(); vVelocityImpulse.z = 0.0f; if ( vVelocityImpulse.IsZero() ) { vVelocityImpulse.x = 1.0f; vVelocityImpulse.y = 1.0f; } VectorNormalize( vVelocityImpulse ); // If impulse is too much along the forward or back axis, skew it Vector vTurretForward, vTurretRight; GetVectors( &vTurretForward, &vTurretRight, NULL ); float fForwardDotImpulse = vTurretForward.Dot( vVelocityImpulse ); if ( fForwardDotImpulse > 0.7f || fForwardDotImpulse < -0.7f ) { vVelocityImpulse += vTurretRight; VectorNormalize( vVelocityImpulse ); } Vector vAngleImpulse( ( vTurretRight.Dot( vVelocityImpulse ) < 0.0f ) ? ( -1.6f ) : ( 1.6f ), RandomFloat( -0.5f, 0.5f ), RandomFloat( -0.5f, 0.5f ) ); vVelocityImpulse *= TURRET_FLOOR_PHYSICAL_FORCE_MULTIPLIER; vAngleImpulse *= TURRET_FLOOR_PHYSICAL_FORCE_MULTIPLIER; pTurretPhys->AddVelocity( &vVelocityImpulse, &vAngleImpulse ); // Check if another turret is hitting us CNPC_Portal_FloorTurret *pPortalFloor = dynamic_cast<CNPC_Portal_FloorTurret*>( pOther ); if ( pPortalFloor && pPortalFloor->m_lifeState == LIFE_ALIVE ) { Vector vTurretVelocity, vOtherVelocity; pTurretPhys->GetVelocity( &vTurretVelocity, NULL ); pOtherPhys->GetVelocity( &vOtherVelocity, NULL ); // If it's moving faster if ( vOtherVelocity.LengthSqr() > vTurretVelocity.LengthSqr() ) { // Make the turret falling onto this one talk pPortalFloor->EmitSound( GetTurretTalkName( PORTAL_TURRET_COLLIDE ) ); pPortalFloor->m_fNextTalk = gpGlobals->curtime + 1.2f; pPortalFloor->m_bDelayTippedTalk = true; // Delay out potential tipped talking so we can here the other turret talk m_fNextTalk = gpGlobals->curtime + 0.6f; m_bDelayTippedTalk = true; } } if ( pPortalFloor && m_bEnabled && m_bLaserOn && !m_bOutOfAmmo ) { // Award friendly fire achievement if we're a live turret being knocked over by another turret. IGameEvent *event = gameeventmanager->CreateEvent( "turret_hit_turret" ); if ( event ) { gameeventmanager->FireEvent( event ); } } } } }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CTDP_NPC_CombineS::Event_Killed( const CTakeDamageInfo &info ) { // Don't bother if we've been told not to, or the player has a megaphyscannon /* if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; }*/ CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( pPlayer != NULL ) { // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. if( IsElite() ) { CBaseEntity *pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); if ( pItem ) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if ( pObj ) { Vector vel = RandomVector( -64.0f, 64.0f ); AngularImpulse angImp = RandomAngularImpulse( -300.0f, 300.0f ); vel[2] = 0.0f; pObj->AddVelocity( &vel, &angImp ); } if( info.GetDamageType() & DMG_DISSOLVE ) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if( pAnimating ) { pAnimating->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } } } } //CTDPGameRules *pTDPGameRules = static_cast<CTDPGameRules *>(g_pGameRules); // Attempt to drop health /*if ( pTDPGameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pTDPGameRules->NPC_DroppedHealth(); }*/ // Attempt to drop a grenade /*if ( pTDPGameRules->NPC_ShouldDropGrenade( pPlayer ) ) { DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pTDPGameRules->NPC_DroppedGrenade(); }*/ } BaseClass::Event_Killed( info ); }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CNPC_CombineAce::Event_Killed( const CTakeDamageInfo &info ) { if (!(g_Language.GetInt() == LANGUAGE_GERMAN || UTIL_IsLowViolence()) && info.GetDamageType() & (DMG_BLAST | DMG_CRUSH) && !(info.GetDamageType() & (DMG_DISSOLVE)) && !PlayerHasMegaPhysCannon()) { Vector vecDamageDir = info.GetDamageForce(); SpawnBlood(GetAbsOrigin(), g_vecAttackDir, BloodColor(), info.GetDamage()); DispatchParticleEffect("headshotspray", GetAbsOrigin(), GetAbsAngles(), this); EmitSound("Gore.Headshot"); float flFadeTime = 25.0; CGib::SpawnSpecificGibs(this, 1, 750, 1500, "models/gibs/soldier_ace_head.mdl", flFadeTime); Vector vecRagForce; vecRagForce.x = random->RandomFloat(-400, 400); vecRagForce.y = random->RandomFloat(-400, 400); vecRagForce.z = random->RandomFloat(0, 250); Vector vecRagDmgForce = (vecRagForce + vecDamageDir); CBaseEntity *pLeftArmGib = CreateRagGib("models/gibs/soldier_ace_left_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftArmGib) { color32 color = pLeftArmGib->GetRenderColor(); pLeftArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightArmGib = CreateRagGib("models/gibs/soldier_ace_right_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightArmGib) { color32 color = pRightArmGib->GetRenderColor(); pRightArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pTorsoGib = CreateRagGib("models/gibs/soldier_ace_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pTorsoGib) { color32 color = pTorsoGib->GetRenderColor(); pTorsoGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pPelvisGib = CreateRagGib("models/gibs/soldier_ace_pelvis.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pPelvisGib) { color32 color = pPelvisGib->GetRenderColor(); pPelvisGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pLeftLegGib = CreateRagGib("models/gibs/soldier_ace_left_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftLegGib) { color32 color = pLeftLegGib->GetRenderColor(); pLeftLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightLegGib = CreateRagGib("models/gibs/soldier_ace_right_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightLegGib) { color32 color = pRightLegGib->GetRenderColor(); pRightLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } //now add smaller gibs. CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p3.mdl", flFadeTime); CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p4.mdl", flFadeTime); if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { pArmor->Remove(); DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); } Vector forceVector = CalcDamageForceVector(info); // Drop any weapon that I own if (VPhysicsGetObject()) { Vector weaponForce = forceVector * VPhysicsGetObject()->GetInvMass(); Weapon_Drop(m_hActiveWeapon, NULL, &weaponForce); } else { Weapon_Drop(m_hActiveWeapon); } if (info.GetAttacker()->IsPlayer()) { ((CSingleplayRules*)GameRules())->NPCKilled(this, info); } UTIL_Remove(this); SetThink(NULL); return; } // Don't bother if we've been told not to, or the player has a megaphyscannon if ( combine_ace_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; } SetEyeState(ACE_EYE_DEAD); if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { pArmor->Remove(); } CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( !pPlayer ) { CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ; if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) { pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() ); } } if ( pPlayer != NULL ) { // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. #ifdef HL2_EPISODIC if (HasSpawnFlags(SF_COMBINE_NO_AR2DROP) == false) #endif { if (FClassnameIs(GetActiveWeapon(), "weapon_ar2")) { CBaseEntity *pItem = DropItem("item_ammo_ar2_altfire", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); if (pItem) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if (pObj) { Vector vel = RandomVector(-64.0f, 64.0f); AngularImpulse angImp = RandomAngularImpulse(-300.0f, 300.0f); vel[2] = 0.0f; pObj->AddVelocity(&vel, &angImp); } if (info.GetDamageType() & DMG_DISSOLVE) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if (pAnimating) { pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL); } } else { WeaponManager_AddManaged(pItem); } } } else if (FClassnameIs(GetActiveWeapon(), "weapon_smg1")) { CBaseEntity *pItem = DropItem("item_ammo_smg1_grenade", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); if (pItem) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if (pObj) { Vector vel = RandomVector(-64.0f, 64.0f); AngularImpulse angImp = RandomAngularImpulse(-300.0f, 300.0f); vel[2] = 0.0f; pObj->AddVelocity(&vel, &angImp); } if (info.GetDamageType() & DMG_DISSOLVE) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if (pAnimating) { pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL); } } else { WeaponManager_AddManaged(pItem); } } } } CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules); // Attempt to drop health if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedHealth(); } if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); } } BaseClass::Event_Killed( info ); }
//----------------------------------------------------------------------------- // Purpose: Fire! //----------------------------------------------------------------------------- void CNPC_Portal_FloorTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy, bool bStrict ) { FireBulletsInfo_t info; //if ( !bStrict && GetEnemy() == UTIL_PlayerByIndex( 1 ) ) CBaseEntity *pEnemy = GetEnemy(); if( !bStrict && (pEnemy && pEnemy->IsPlayer()) ) { Vector vecDir = GetActualShootTrajectory( vecSrc ); info.m_vecSrc = vecSrc; info.m_vecDirShooting = vecDir; info.m_iTracerFreq = 1; info.m_iShots = 1; info.m_pAttacker = this; info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() ); info.m_flDistance = MAX_COORD_RANGE; info.m_iAmmoType = m_iAmmoType; } else { // Just shoot where you're facing! Vector vecMuzzle, vecMuzzleDir; GetAttachment( m_iMuzzleAttachment, vecMuzzle, &vecMuzzleDir ); info.m_vecSrc = vecSrc; info.m_vecDirShooting = vecMuzzleDir; info.m_iTracerFreq = 1; info.m_iShots = 1; info.m_pAttacker = this; info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() ); info.m_flDistance = MAX_COORD_RANGE; info.m_iAmmoType = m_iAmmoType; } info.m_flDamageForceScale = ( ( !m_bDamageForce ) ? ( 0.0f ) : ( TURRET_FLOOR_BULLET_FORCE_MULTIPLIER ) ); int iBarrelIndex = ( m_bShootWithBottomBarrels ) ? ( 2 ) : ( 0 ); QAngle angBarrelDir; // Shoot out of the left barrel if there's nothing solid between the turret's center and the muzzle trace_t tr; GetAttachment( m_iBarrelAttachments[ iBarrelIndex ], info.m_vecSrc, angBarrelDir ); Vector vecCenter = GetAbsOrigin(); UTIL_TraceLine( vecCenter, info.m_vecSrc, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( !tr.m_pEnt || !tr.m_pEnt->IsWorld() ) { FireBullets( info ); } // Shoot out of the right barrel if there's nothing solid between the turret's center and the muzzle GetAttachment( m_iBarrelAttachments[ iBarrelIndex + 1 ], info.m_vecSrc, angBarrelDir ); vecCenter = GetAbsOrigin(); UTIL_TraceLine( vecCenter, info.m_vecSrc, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( !tr.m_pEnt || !tr.m_pEnt->IsWorld() ) { FireBullets( info ); } // Flip shooting from the top or bottom m_bShootWithBottomBarrels = !m_bShootWithBottomBarrels; EmitSound( "NPC_FloorTurret.ShotSounds" ); DoMuzzleFlash(); // Make ropes shake if they exist for ( int iRope = 0; iRope < PORTAL_FLOOR_TURRET_NUM_ROPES; ++iRope ) { if ( m_hRopes[ iRope ] ) { m_hRopes[ iRope ]->ShakeRopes( vecSrc, 32.0f, 5.0f ); } } // If a turret is partially tipped the recoil with each shot so that it can knock itself over Vector up; GetVectors( NULL, NULL, &up ); if ( up.z < 0.9f ) { m_pMotionController->Suspend( 2.0f ); IPhysicsObject *pTurretPhys = VPhysicsGetObject(); Vector vVelocityImpulse = info.m_vecDirShooting * -35.0f; pTurretPhys->AddVelocity( &vVelocityImpulse, &vVelocityImpulse ); } if ( m_iLastState == TURRET_ACTIVE && gpGlobals->curtime > m_fNextTalk ) { EmitSound( GetTurretTalkName( m_iLastState ) ); m_fNextTalk = gpGlobals->curtime + 2.5f; } }
//----------------------------------------------------------------------------- // Purpose: Spawn an instance of the entity //----------------------------------------------------------------------------- void CEnvEntityMaker::SpawnEntity( Vector vecAlternateOrigin, QAngle vecAlternateAngles ) { CPointTemplate *pTemplate = FindTemplate(); if (!pTemplate) return; // Spawn our template Vector vecSpawnOrigin = GetAbsOrigin(); QAngle vecSpawnAngles = GetAbsAngles(); if( vecAlternateOrigin != vec3_invalid ) { // We have a valid alternate origin and angles. Use those instead // of spawning the items at my own origin and angles. vecSpawnOrigin = vecAlternateOrigin; vecSpawnAngles = vecAlternateAngles; } CUtlVector<CBaseEntity*> hNewEntities; if ( !pTemplate->CreateInstance( vecSpawnOrigin, vecSpawnAngles, &hNewEntities, this ) ) return; //Adrian: oops we couldn't spawn the entity (or entities) for some reason! if ( hNewEntities.Count() == 0 ) return; m_hCurrentInstance = hNewEntities[0]; // Assume it'll block us m_hCurrentBlocker = m_hCurrentInstance; m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin(); // Store off the mins & maxs the first time we spawn if ( m_vecEntityMins == vec3_origin ) { m_hCurrentInstance->CollisionProp()->WorldSpaceAABB( &m_vecEntityMins, &m_vecEntityMaxs ); m_vecEntityMins -= m_hCurrentInstance->GetAbsOrigin(); m_vecEntityMaxs -= m_hCurrentInstance->GetAbsOrigin(); } // Fire our output m_pOutputOnSpawned.FireOutput( this, this ); // Start thinking if ( m_spawnflags & SF_ENTMAKER_AUTOSPAWN ) { SetThink( &CEnvEntityMaker::CheckSpawnThink ); SetNextThink( gpGlobals->curtime + 0.5f ); } // If we have a specified post spawn speed, apply it to all spawned entities if ( m_flPostSpawnSpeed ) { for ( int i = 0; i < hNewEntities.Count(); i++ ) { CBaseEntity *pEntity = hNewEntities[i]; if ( pEntity->GetMoveType() == MOVETYPE_NONE ) continue; // Calculate a velocity for this entity Vector vForward,vRight,vUp; QAngle angSpawnDir( m_angPostSpawnDirection ); if ( m_bPostSpawnUseAngles ) { if ( GetParent() ) { angSpawnDir += GetParent()->GetAbsAngles(); } else { angSpawnDir += GetAbsAngles(); } } AngleVectors( angSpawnDir, &vForward, &vRight, &vUp ); Vector vecShootDir = vForward; vecShootDir += vRight * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; vecShootDir += vForward * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; vecShootDir += vUp * random->RandomFloat(-1, 1) * m_flPostSpawnDirectionVariance; VectorNormalize( vecShootDir ); vecShootDir *= m_flPostSpawnSpeed; // Apply it to the entity IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity(&vecShootDir, NULL); } else { pEntity->SetAbsVelocity( vecShootDir ); } } } pTemplate->CreationComplete( hNewEntities ); }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info ) { // Don't bother if we've been told not to, or the player has a megaphyscannon if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; } CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( !pPlayer ) { CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ; if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) { pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() ); } } if ( pPlayer != NULL ) { // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. if( IsElite() ) { #ifdef HL2_EPISODIC if ( HasSpawnFlags( SF_COMBINE_NO_AR2DROP ) == false ) #endif { CBaseEntity *pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); if ( pItem ) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if ( pObj ) { Vector vel = RandomVector( -64.0f, 64.0f ); AngularImpulse angImp = RandomAngularImpulse( -300.0f, 300.0f ); vel[2] = 0.0f; pObj->AddVelocity( &vel, &angImp ); } if( info.GetDamageType() & DMG_DISSOLVE ) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if( pAnimating ) { pAnimating->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } } else { WeaponManager_AddManaged( pItem ); } } } } CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules); // Attempt to drop health if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedHealth(); } if ( HasSpawnFlags( SF_COMBINE_NO_GRENADEDROP ) == false ) { // Attempt to drop a grenade if ( pHL2GameRules->NPC_ShouldDropGrenade( pPlayer ) ) { DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedGrenade(); } } } BaseClass::Event_Killed( info ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Dog::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_DOG_PICKUP_ITEM: { PullObject( false ); } break; case TASK_DOG_GET_PATH_TO_PHYSOBJ: { //Check this cause our object might have been deleted. if ( m_hPhysicsEnt == NULL ) FindPhysicsObject( NULL ); //And if we still can't find anything, then just go away. if ( m_hPhysicsEnt == NULL ) { TaskFail( "Can't find an object I like!" ); return; } IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject(); Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; if ( m_hPhysicsEnt->GetOwnerEntity() == NULL ) m_hPhysicsEnt->SetOwnerEntity( this ); if ( pPhysicsObject ) pPhysicsObject->RecheckCollisionFilter(); vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); bool bBuiltRoute = false; //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( bBuiltRoute == true ) TaskComplete(); else { m_flTimeToCatch = gpGlobals->curtime + 0.1; m_flNextRouteTime = gpGlobals->curtime + 0.3; m_flNextSwat = gpGlobals->curtime + 0.1; if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 ) m_hUnreachableObjects.AddToTail( m_hPhysicsEnt ); m_hPhysicsEnt = NULL; GetNavigator()->ClearGoal(); } } break; case TASK_WAIT: { if ( IsWaitFinished() ) { TaskComplete(); } if ( m_hPhysicsEnt ) { if ( m_bHasObject == false ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } } break; } case TASK_DOG_LAUNCH_ITEM: if( IsActivityFinished() ) { if ( m_hPhysicsEnt ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); } TaskComplete(); } break; case TASK_DOG_WAIT_FOR_TARGET_TO_FACE: { if ( CanTargetSeeMe() ) TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: { if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() ) { BaseClass::RunTask( pTask ); return; } if ( m_hPhysicsEnt != NULL ) { IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" ); } if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) TaskFail( "Player picked it up!" ); //If the object is moving then my old goal might not be valid //cancel the schedule and make it restart again in a bit. if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); float flDistance = (vecGoalPos - GetLocalOrigin()).Length(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST ) { TaskComplete(); GetNavigator()->StopMoving(); } } } BaseClass::RunTask( pTask ); } break; case TASK_DOG_WAIT_FOR_OBJECT: { if ( m_hPhysicsEnt != NULL ) { if ( FVisible( m_hPhysicsEnt ) == false ) { m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Lost sight of the object!" ); m_hPhysicsEnt->SetOwnerEntity( NULL ); return; } m_hPhysicsEnt->SetOwnerEntity( this ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); Vector vGunPos; GetAttachment( m_iPhysGunAttachment, vGunPos ); Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos; float flDistance = vToObject.Length(); VectorNormalize( vToObject ); SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() ); #ifdef SecobMod__Enable_Fixed_Multiplayer_AI CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); #else CBasePlayer *pPlayer = AI_GetSinglePlayer(); #endif //SecobMod__Enable_Fixed_Multiplayer_AI float flDistanceToPlayer = flDistance; if ( pPlayer ) { flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length(); } IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog: TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" ); } if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) ) { if ( m_flTimeToPull <= gpGlobals->curtime ) { Vector vCurrentVel; float flCurrentVel; AngularImpulse vCurrentAI; pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI ); flCurrentVel = vCurrentVel.Length(); VectorNormalize( vCurrentVel ); if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE ) { Vector vDir = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ); VectorNormalize( vDir ); vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD ); vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD; pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI ); vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD; Vector vAngle( 0, 0, 0 ); pPhysObj->AddVelocity( &vDir, &vAngle ); CreateBeams(); } float flDot = DotProduct( vCurrentVel, vForward ); if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 ) { if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); } } } } float flDirDot = DotProduct( vToObject, vForward ); if ( flDirDot < 0.2 ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Done waiting!" ); } else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) ) { AngularImpulse vZero( 0, 0, 0 ); pPhysObj->SetVelocity( &vec3_origin, &vZero ); GetNavigator()->StopMoving(); //Fire Output! m_OnCatch.FireOutput( this, this ); m_bHasObject = true; ClearBeams(); TaskComplete(); } } else { GetNavigator()->StopMoving(); ClearBeams(); TaskFail("No Physics Object!"); } } break; case TASK_DOG_CATCH_OBJECT: if( IsActivityFinished() ) { m_flTimeToCatch = 0.0f; TaskComplete(); } break; default: BaseClass::RunTask( pTask ); break; } }
CBaseEntity *BreakModelCreateSingle( CBaseEntity *pOwner, breakmodel_t *pModel, const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, int nSkin, const breakablepropparams_t ¶ms ) { C_PhysPropClientside *pEntity = C_PhysPropClientside::CreateNew(); if ( !pEntity ) return NULL; // UNDONE: Allow .qc to override spawnflags for child pieces C_PhysPropClientside *pBreakableOwner = dynamic_cast<C_PhysPropClientside *>(pOwner); // Inherit the base object's damage modifiers if ( pBreakableOwner ) { pEntity->SetEffects( pBreakableOwner->GetEffects() ); pEntity->m_spawnflags = pBreakableOwner->m_spawnflags; // We never want to be motion disabled pEntity->m_spawnflags &= ~SF_PHYSPROP_MOTIONDISABLED; pEntity->SetDmgModBullet( pBreakableOwner->GetDmgModBullet() ); pEntity->SetDmgModClub( pBreakableOwner->GetDmgModClub() ); pEntity->SetDmgModExplosive( pBreakableOwner->GetDmgModExplosive() ); // FIXME: If this was created from a client-side entity which was in the // middle of ramping the fade scale, we're screwed. pEntity->CopyFadeFrom( pBreakableOwner ); } pEntity->SetModelName( AllocPooledString( pModel->modelName ) ); pEntity->SetLocalOrigin( position ); pEntity->SetLocalAngles( angles ); pEntity->SetOwnerEntity( pOwner ); pEntity->SetPhysicsMode( PHYSICS_MULTIPLAYER_CLIENTSIDE ); if ( !pEntity->Initialize() ) { pEntity->Release(); return NULL; } pEntity->m_nSkin = nSkin; pEntity->m_iHealth = pModel->health; #ifdef TF_CLIENT_DLL pEntity->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); #endif #ifdef DOD_DLL pEntity->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); #endif if ( pModel->health == 0 ) { // if no health, don't collide with player anymore, don't take damage pEntity->m_takedamage = DAMAGE_NO; if ( pEntity->GetCollisionGroup() == COLLISION_GROUP_PUSHAWAY ) { pEntity->SetCollisionGroup( COLLISION_GROUP_NONE ); } } if ( pModel->fadeTime > 0 ) { pEntity->StartFadeOut( pModel->fadeTime ); } if ( pModel->fadeMinDist > 0 && pModel->fadeMaxDist >= pModel->fadeMinDist ) { pEntity->SetFadeMinMax( pModel->fadeMinDist, pModel->fadeMaxDist ); } if ( pModel->isRagdoll ) { DevMsg( "BreakModelCreateSingle: clientside doesn't support ragdoll breakmodels.\n" ); } IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if( pPhysicsObject ) { // randomize velocity by 5% float rndf = RandomFloat( -0.025, 0.025 ); Vector rndVel = velocity + rndf*velocity; pPhysicsObject->AddVelocity( &rndVel, &angVelocity ); } else { // failed to create a physics object pEntity->Release(); return NULL; } return pEntity; }
void CNPC_Dog::PullObject( bool bMantain ) { if ( m_hPhysicsEnt == NULL ) { TaskFail( "Ack! No Phys Object!"); return; } IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( pPhysObj == NULL ) { TaskFail( "Pulling object with no Phys Object?!" ); return; } if( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { m_bHasObject = false; ClearBeams(); TaskFail("Player Grabbed Ball"); return; } CreateBeams(); Vector vGunPos; GetAttachment( m_iPhysGunAttachment, vGunPos ); float flDistance = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ).Length(); if ( bMantain == false ) { if ( flDistance <= DOG_CATCH_DISTANCE ) { m_hPhysicsEnt->SetOwnerEntity( this ); GetNavigator()->StopMoving(); //Fire Output! m_OnPickup.FireOutput( this, this ); m_bHasObject = true; ClearBeams(); TaskComplete(); return; } } Vector vDir = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ); Vector vCurrentVel; float flCurrentVel; AngularImpulse vCurrentAI; pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI ); flCurrentVel = vCurrentVel.Length(); VectorNormalize( vCurrentVel ); VectorNormalize( vDir ); float flVelMod = DOG_PULL_VELOCITY_MOD; if ( bMantain == true ) flVelMod *= 2; vCurrentVel = vCurrentVel * flCurrentVel * flVelMod; vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD; pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI ); vDir = vDir * flDistance * (DOG_PULL_TO_GUN_VEL_MOD * 2); Vector vAngle( 0, 0, 0 ); pPhysObj->AddVelocity( &vDir, &vAngle ); }
//----------------------------------------------------------------------------- // Create a corpse //----------------------------------------------------------------------------- void CPropAPC2::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < APC_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics_multiplayer" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); /*if ( flMass < 200 ) {*/ Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); /*}*/ //pGib->Ignite( 60, false ); pGib->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } // CPropAPC2 *pAPC = (CPropAPC2 *)CreateEntityByName( "prop_vehicle_apc2" ); if ( pAPC ) { pAPC->InicialSpawn=m_vOriginalSpawnOrigin; pAPC->InicialAngle=m_vOriginalSpawnAngles; pAPC->m_bSpawn=true; pAPC->SetThink( &CPropAPC2::Materialize ); pAPC->SetContextThink( &CPropAPC2::Materialize, gpGlobals->curtime + 5.0f, "RESPAWNING" ); pAPC->SetNextThink( gpGlobals->curtime + 5.0f ); } else { Warning("Respawn failed to create %s!\n", GetClassname() ); } // AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_Remove( this ); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CGrenade_Brickbat::BrickbatThink( void ) { // ----------------------------------------------------------- // Might be physically simulated so get my velocity manually // ----------------------------------------------------------- Vector vVelocity; AngularImpulse vAngVel; GetVelocity(&vVelocity,&vAngVel); // See if I can lose my owner (has dropper moved out of way?) // Want do this so owner can throw the brickbat if (GetOwnerEntity()) { trace_t tr; Vector vUpABit = GetAbsOrigin(); vUpABit.z += 5.0; CBaseEntity* saveOwner = GetOwnerEntity(); SetOwnerEntity( NULL ); UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr ); if ( tr.startsolid || tr.fraction != 1.0 ) { SetOwnerEntity( saveOwner ); } } // --------------------------------------------------------------- // Make sure we're not resting on a living thing's bounding box // --------------------------------------------------------------- if (vVelocity.Length() < 0.01) { trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0 && tr.m_pEnt) { CBaseEntity *pEntity = tr.m_pEnt; if (pEntity->GetFlags() & (FL_CLIENT | FL_NPC)) { // -------------------- // Bounce me off // -------------------- Vector vNewVel; vNewVel.y = 100; vNewVel.x = random->RandomInt(-100,100); vNewVel.z = random->RandomInt(-100,100); // If physically simulated IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->AddVelocity( &vNewVel, &vAngVel ); } // Otherwise else { SetAbsVelocity( vNewVel ); } } } } if (vVelocity.Length() < 0.01) { SpawnBrickbatWeapon(); } SetNextThink( gpGlobals->curtime + 0.1f ); }