//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseProjectile::ProjectileTouch( CBaseEntity *pOther ) { // Verify a correct "other." Assert( pOther ); if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) ) return; // Handle hitting skybox (disappear). const trace_t *pTrace = &CBaseEntity::GetTouchTrace(); trace_t *pNewTrace = const_cast<trace_t*>( pTrace ); if( pTrace->surface.flags & SURF_SKY ) { UTIL_Remove( this ); return; } CTakeDamageInfo info; info.SetAttacker( GetOwnerEntity() ); info.SetInflictor( this ); info.SetDamage( GetDamage() ); info.SetDamageType( GetDamageType() ); CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin(), GetDamageScale() ); Vector dir; AngleVectors( GetAbsAngles(), &dir ); pOther->DispatchTraceAttack( info, dir, pNewTrace ); ApplyMultiDamage(); UTIL_Remove( this ); }
void CControllerZapBall::ExplodeTouch( CBaseEntity *pOther ) { if (pOther->pev->takedamage) { TraceResult tr = UTIL_GetGlobalTrace( ); entvars_t *pevOwner; if (m_hOwner != NULL) { pevOwner = m_hOwner->pev; } else { pevOwner = pev; } ClearMultiDamage( ); pOther->TraceAttack(pevOwner, gSkillData.controllerDmgBall, pev->velocity.Normalize(), &tr, DMG_ENERGYBEAM ); ApplyMultiDamage( pevOwner, pevOwner ); UTIL_EmitAmbientSound( ENT(pev), tr.vecEndPos, "weapons/electro4.wav", 0.3, ATTN_NORM, 0, RANDOM_LONG( 90, 99 ) ); } UTIL_Remove( this ); }
void CMmissile::ExplodeTouch( CBaseEntity *pOther ) { if ( UTIL_PointContents(pev->origin) == CONTENT_SKY ) { FX_Trail( pev->origin, entindex(), PROJ_REMOVE ); UTIL_Remove( this ); return; } if (pOther->pev->health == 666) { return; } TraceResult tr; Vector vecSpot = pev->origin - pev->velocity.Normalize() * 32; Vector vecEnd = pev->origin + pev->velocity.Normalize() * 64; UTIL_TraceLine( vecSpot, vecEnd, ignore_monsters, ENT(pev), &tr ); entvars_t *pevOwner = VARS( pev->owner ); RadiusDamage ( pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST ); FX_Trail( tr.vecEndPos + (tr.vecPlaneNormal * 15), entindex(), (UTIL_PointContents(pev->origin) == CONTENT_WATER)?PROJ_MMISSILE_DETONATE_WATER:PROJ_MMISSILE_DETONATE ); int tex = (int)TEXTURETYPE_Trace(&tr, vecSpot, vecEnd); CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); FX_ImpRocket( tr.vecEndPos, tr.vecPlaneNormal, pEntity->IsBSPModel()?1:0, BULLET_SMALEXP, (float)tex ); if (pOther->pev->takedamage) { ClearMultiDamage( ); pOther->TraceAttack(pevOwner, pev->dmg/3, gpGlobals->v_forward, &tr, DMG_BULLETMAGNUM ); ApplyMultiDamage( pev, pevOwner); } UTIL_Remove( this ); }
void CTankProj::ExplodeTouch( CBaseEntity *pOther ) { if ( UTIL_PointContents(pev->origin) == CONTENT_SKY ) { UTIL_Remove( this ); return; } TraceResult tr; Vector vecSpot = pev->origin - pev->velocity.Normalize() * 32; Vector vecEnd = pev->origin + pev->velocity.Normalize() * 64; UTIL_TraceLine( vecSpot, vecEnd, ignore_monsters, ENT(pev), &tr ); int tex = (int)TEXTURETYPE_Trace(&tr, vecSpot, vecEnd); CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); FX_ImpRocket( tr.vecEndPos, tr.vecPlaneNormal, pEntity->IsBSPModel()?1:0, BULLET_HIGHEXP, (float)tex ); entvars_t *pevOwner = VARS( pev->owner ); ::RadiusDamage( pev->origin, pev, pevOwner, pev->dmg, pev->dmg*0.8, CLASS_NONE, DMG_BLAST); FX_Explosion( tr.vecEndPos + (tr.vecPlaneNormal * 25), EXPLOSION_TANKPROJ ); if (pOther->pev->takedamage) { ClearMultiDamage( ); pOther->TraceAttack(pevOwner, pev->dmg/4, gpGlobals->v_forward, &tr, DMG_BULLETMAGNUM ); ApplyMultiDamage( pev, pevOwner); } UTIL_Remove( this ); }
void FireSentryBulletsNEW( int shotcount, gedict_t * targ, float spread_x, float spread_y, float spread_z ) { vec3_t src; vec3_t dst; vec3_t norm_dir; sgAimNew( self, targ, src, dst, norm_dir ); ClearMultiDamage( ); traceline( PASSVEC3( src ), PASSVEC3( dst ), 0, self ); VectorScale( norm_dir, 4, puff_org ); VectorSubtract( g_globalvars.trace_endpos, puff_org, puff_org ); for ( ; shotcount > 0 ; shotcount-- ) { // для каждого выстрела определяем trace_ent trace_endpos // т.к.выстрелы могут убрать препятствия traceline( PASSVEC3( src ), PASSVEC3( dst ), 0, self ); // TraceAttack требует нормализованый вектор для корректного определения blood_org if(g_globalvars.trace_fraction != 1) TraceAttack( 4, norm_dir ); } ApplyMultiDamage( ); Multi_Finish( ); }
// Quake Bullet firing void CBasePlayer::Q_FireBullets(int iShots, Vector vecDir, Vector vecSpread) { TraceResult trace; UTIL_MakeVectors(pev->v_angle); Vector vecSrc = pev->origin + (gpGlobals->v_forward * 10); vecSrc.z = pev->absmin.z + (pev->size.z * 0.7); ClearMultiDamage(); while(iShots > 0) { Vector vecPath = vecDir + (RANDOM_FLOAT(-1, 1) * vecSpread.x * gpGlobals->v_right) + (RANDOM_FLOAT(-1, 1) * vecSpread.y * gpGlobals->v_up); Vector vecEnd = vecSrc + (vecPath * 2048); UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &trace); if(trace.flFraction != 1.0) { CBaseEntity *pEntity = CBaseEntity::Instance(trace.pHit); if(pEntity && pEntity->pev->takedamage && pEntity->IsPlayer()) { pEntity->TraceAttack(pev, 4, vecPath, &trace, DMG_BULLET); //AddMultiDamage(pev, pEntity, 4, DMG_BULLET); } else if(pEntity && pEntity->pev->takedamage) { pEntity->TakeDamage(pev, pev, 4, DMG_BULLET); } } iShots--; } ApplyMultiDamage(pev, pev); }
void CGrenade::BounceTouch( CBaseEntity *pOther ) { // don't hit the guy that launched this grenade if ( pOther->edict() == pev->owner ) return; // only do damage if we're moving fairly fast if (m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100) { entvars_t *pevOwner = VARS( pev->owner ); if (pevOwner) { TraceResult tr = UTIL_GetGlobalTrace( ); ClearMultiDamage( ); pOther->TraceAttack(pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB ); ApplyMultiDamage( pev, pevOwner); } m_flNextAttack = gpGlobals->time + 1.0; // debounce } Vector vecTestVelocity; // pev->avelocity = Vector (300, 300, 300); // this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical // or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. // trimming the Z velocity a bit seems to help quite a bit. vecTestVelocity = pev->velocity; vecTestVelocity.z *= 0.45; if ( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 ) { //ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() ); // grenade is moving really slow. It's probably very close to where it will ultimately stop moving. // go ahead and emit the danger sound. // register a radius louder than the explosion, so we make sure everyone gets out of the way CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 ); m_fRegisteredSound = TRUE; } if (pev->flags & FL_ONGROUND) { // add a bit of static friction pev->velocity = pev->velocity * 0.8; pev->sequence = RANDOM_LONG( 1, 1 ); } else { // play bounce sound BounceSound(); } pev->framerate = pev->velocity.Length() / 200.0; if (pev->framerate > 1.0) pev->framerate = 1; else if (pev->framerate < 0.5) pev->framerate = 0; }
void CFlame::Fly( void ) { if ( pev->frags <= 0 || UTIL_PointContents(pev->origin) == CONTENT_WATER ) { FX_Trail( pev->origin, entindex(), PROJ_REMOVE ); UTIL_Remove( this ); return; } pev->frags--; entvars_t *pevOwner = VARS(pev->owner); CBaseEntity *pOther = NULL; while ((pOther = UTIL_FindEntityInSphere( pOther, pev->origin, 50 )) != NULL) { if (pOther->edict() != pev->owner && pOther->pev->takedamage && pOther->Classify() != CLASS_MACHINE ) { TraceResult tr; UTIL_TraceLine( pev->origin, pOther->pev->origin, dont_ignore_monsters, ENT(pev), &tr ); CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); ClearMultiDamage( ); pEntity->TraceAttack( pevOwner, pev->dmg/3, pev->velocity, &tr, DMG_IGNITE | DMG_NEVERGIB); ApplyMultiDamage( pev, pevOwner ); } } pev->nextthink = gpGlobals->time + 0.1; }
void CNPC_ControllerZapBall::ExplodeTouch( CBaseEntity *pOther ) { if (m_takedamage = DAMAGE_YES ) { trace_t tr; tr = GetTouchTrace( ); ClearMultiDamage( ); Vector vecAttackDir = GetAbsVelocity(); VectorNormalize( vecAttackDir ); if (m_hOwner != NULL) { CTakeDamageInfo info( this, m_hOwner, sk_controller_dmgball.GetFloat(), DMG_ENERGYBEAM ); CalculateMeleeDamageForce( &info, vecAttackDir, tr.endpos ); pOther->DispatchTraceAttack( info, vecAttackDir, &tr ); } else { CTakeDamageInfo info( this, this, sk_controller_dmgball.GetFloat(), DMG_ENERGYBEAM ); CalculateMeleeDamageForce( &info, vecAttackDir, tr.endpos ); pOther->DispatchTraceAttack( info, vecAttackDir, &tr ); } ApplyMultiDamage(); // void UTIL_EmitAmbientSound( CBaseEntity *entity, const Vector &vecOrigin, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float soundtime /*= 0.0f*/ ) UTIL_EmitAmbientSound( GetSoundSourceIndex(), tr.endpos, "Controller.ElectroSound", 0.3, SNDLVL_NORM, 0, random->RandomInt( 90, 99 ) ); } Kill(); }
void CNPC_Hydra::Stab( CBaseEntity *pOther, const Vector &vecSpeed, trace_t &tr ) { if (pOther->m_takedamage == DAMAGE_YES && !pOther->IsPlayer()) { Vector dir = vecSpeed; VectorNormalize( dir ); if ( !sv_hydraTestSpike.GetInt() ) { ClearMultiDamage(); // FIXME: this is bogus CTakeDamageInfo info( this, this, pOther->m_iHealth+25, DMG_SLASH ); CalculateMeleeDamageForce( &info, dir, tr.endpos ); pOther->DispatchTraceAttack( info, dir, &tr ); ApplyMultiDamage(); } else { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating *>(pOther); if ( pAnimating ) { AttachStabbedEntity( pAnimating, vecSpeed * 30, tr ); } } } else { Nudge( pOther, tr.endpos, vecSpeed ); } }
//------------------------------------------------------------------------------ // Purpose: Implement impact function //------------------------------------------------------------------------------ void CWeaponCrowbar::Hit( void ) { //Make sound for the AI #ifndef CLIENT_DLL CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); CSoundEnt::InsertSound( SOUND_BULLET_IMPACT, m_traceHit.endpos, 400, 0.2f, pPlayer ); CBaseEntity *pHitEntity = m_traceHit.m_pEnt; //Apply damage to a hit target if ( pHitEntity != NULL ) { Vector hitDirection; pPlayer->EyeVectors( &hitDirection, NULL, NULL ); VectorNormalize( hitDirection ); ClearMultiDamage(); CTakeDamageInfo info( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB ); CalculateMeleeDamageForce( &info, hitDirection, m_traceHit.endpos ); pHitEntity->DispatchTraceAttack( info, hitDirection, &m_traceHit ); ApplyMultiDamage(); // Now hit all triggers along the ray that... TraceAttackToTriggers( CTakeDamageInfo( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB ), m_traceHit.startpos, m_traceHit.endpos, hitDirection ); //Play an impact sound ImpactSound( pHitEntity ); } #endif //Apply an impact effect ImpactEffect(); }
//=====================================================================================// // Purpose: Performs the screen shake and it checks to see if we hit an entity to // handle the proper damage // An entity here can be another player or a wood plank //=====================================================================================// void CTDPBludgeonWeaponBase::Hit( trace_t &tr, Activity nHitActivity ) { // Do we have a valid owner holding the weapon? CTDPPlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; // Let's shake the screen a little AddViewKick(); // if tr.m_pEnt is not NULL it means we have hit a target if ( tr.m_pEnt != NULL ) { Vector vForward; pPlayer->EyeVectors( &vForward, NULL, NULL ); VectorNormalize( vForward ); // Process the damage and send it to the entity we just hit CTakeDamageInfo dmgInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB ); CalculateMeleeDamageForce( &dmgInfo, vForward, tr.endpos ); tr.m_pEnt->DispatchTraceAttack( dmgInfo, vForward, &tr ); ApplyMultiDamage(); #if defined( GAME_DLL ) // Now hit all triggers along the ray that... TraceAttackToTriggers( dmgInfo, tr.startpos, tr.endpos, vForward ); #endif } // Apply an impact effect ImpactEffect( tr ); }
void CFlechette::DoAOEDamage() { CBaseEntity *ppEnts[256]; Vector vecCenter = WorldSpaceCenter(); float flRadius = flechette_radius.GetFloat(); vecCenter.z -= flRadius * 0.8f; int nEntCount = UTIL_EntitiesInSphere( ppEnts, 256, vecCenter, flRadius, 0 ); int i; for ( i = 0; i < nEntCount; i++ ) { if ( ppEnts[i] == NULL ) continue; bool bDoDamage = true; if(ppEnts[i]->IsPlayer() || ppEnts[i]->IsNPC()) { CBasePlayer *pOtherPlayer = ToBasePlayer(ppEnts[i]); CBasePlayer *pPlayer = ToBasePlayer(GetOwnerEntity()); if(pOtherPlayer != NULL && pPlayer != NULL) { if((HL2MPRules()->IsTeamplay() && (pPlayer->GetTeamNumber() == pOtherPlayer->GetTeamNumber())) || HL2MPRules()->GetGameType() == GAME_COOP) { const int oldHealth = pOtherPlayer->GetHealth(); pOtherPlayer->TakeHealth( HEAL_AMOUNT, DMG_GENERIC ); bDoDamage = false; if(oldHealth <= HEAL_AMOUNT) pOtherPlayer->PlayAutovocal(HEALED,0); if(oldHealth != pOtherPlayer->GetHealth()) // Si on a vraiment heal pOtherPlayer->EmitSound("Tranqu.Heal"); } } if(bDoDamage && ppEnts[i] != GetOwnerEntity()) { int iApplyDamage = 0; if(ppEnts[i]->IsNPC()) iApplyDamage = 70; else { if(ppEnts[i]->GetHealth() < m_iDamage + 10) iApplyDamage = 100; else iApplyDamage = ppEnts[i]->GetHealth() - m_iDamage; } CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), GetOwnerEntity(), iApplyDamage, DMG_POISON | DMG_NEVERGIB ); //CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( vecCenter ); ppEnts[i]->TakeDamage(dmgInfo); //ppEnts[i]->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); } } ApplyMultiDamage(); } }
void AddMultiDamage( gedict_t * hit, float damage ) { if ( !hit ) return; if ( hit != multi_ent ) { ApplyMultiDamage(); multi_damage = damage; multi_ent = hit; } else multi_damage = multi_damage + damage; }
//----------------------------------------------------------------------------- // Purpose: Add damage to the existing multidamage, and apply if it won't fit //----------------------------------------------------------------------------- void AddMultiDamage( const CTakeDamageInfo &info, CBaseEntity *pEntity ) { if ( !pEntity ) return; if ( pEntity != g_MultiDamage.GetTarget() ) { ApplyMultiDamage(); g_MultiDamage.Init( pEntity, info.GetInflictor(), info.GetAttacker(), info.GetWeapon(), vec3_origin, vec3_origin, vec3_origin, 0.0, info.GetDamageType(), info.GetDamageCustom() ); } g_MultiDamage.AddDamageType( info.GetDamageType() ); g_MultiDamage.SetDamage( g_MultiDamage.GetDamage() + info.GetDamage() ); g_MultiDamage.SetDamageForce( g_MultiDamage.GetDamageForce() + info.GetDamageForce() ); g_MultiDamage.SetDamagePosition( info.GetDamagePosition() ); g_MultiDamage.SetReportedPosition( info.GetReportedPosition() ); g_MultiDamage.SetMaxDamage( MAX( g_MultiDamage.GetMaxDamage(), info.GetDamage() ) ); g_MultiDamage.SetAmmoType( info.GetAmmoType() ); if ( g_MultiDamage.GetPlayerPenetrationCount() == 0 ) { g_MultiDamage.SetPlayerPenetrationCount( info.GetPlayerPenetrationCount() ); } bool bHasPhysicsForceDamage = !g_pGameRules->Damage_NoPhysicsForce( info.GetDamageType() ); if ( bHasPhysicsForceDamage && g_MultiDamage.GetDamageType() != DMG_GENERIC ) { // If you hit this assert, you've called TakeDamage with a damage type that requires a physics damage // force & position without specifying one or both of them. Decide whether your damage that's causing // this is something you believe should impart physics force on the receiver. If it is, you need to // setup the damage force & position inside the CTakeDamageInfo (Utility functions for this are in // takedamageinfo.cpp. If you think the damage shouldn't cause force (unlikely!) then you can set the // damage type to DMG_GENERIC, or | DMG_CRUSH if you need to preserve the damage type for purposes of HUD display. if ( g_MultiDamage.GetDamageForce() == vec3_origin || g_MultiDamage.GetDamagePosition() == vec3_origin ) { static int warningCount = 0; if ( ++warningCount < 10 ) { if ( g_MultiDamage.GetDamageForce() == vec3_origin ) { Warning( "AddMultiDamage: g_MultiDamage.GetDamageForce() == vec3_origin\n" ); } if ( g_MultiDamage.GetDamagePosition() == vec3_origin) { Warning( "AddMultiDamage: g_MultiDamage.GetDamagePosition() == vec3_origin\n" ); } } } } }
//----------------------------------------------------------------------------- // Purpose: Called at the end of GameFrame (i.e. after all game logic has run this frame) //----------------------------------------------------------------------------- void CGameRules::EndGameFrame( void ) { // If you hit this assert, it means something called AddMultiDamage() and didn't ApplyMultiDamage(). // The g_MultiDamage.m_hAttacker & g_MultiDamage.m_hInflictor should give help you figure out the culprit. Assert( g_MultiDamage.IsClear() ); if ( !g_MultiDamage.IsClear() ) { Warning("Unapplied multidamage left in the system:\nTarget: %s\nInflictor: %s\nAttacker: %s\nDamage: %.2f\n", g_MultiDamage.GetTarget()->GetDebugName(), g_MultiDamage.GetInflictor()->GetDebugName(), g_MultiDamage.GetAttacker()->GetDebugName(), g_MultiDamage.GetDamage() ); ApplyMultiDamage(); } }
void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { if ( !pEntity ) return; gMultiDamage.type |= bitsDamageType; if ( pEntity != gMultiDamage.pEntity ) { ApplyMultiDamage(pevInflictor,pevInflictor); // UNDONE: wrong attacker! gMultiDamage.pEntity = pEntity; gMultiDamage.amount = 0; } gMultiDamage.amount += flDamage; }
//------------------------------------------------------------------------------ // Purpose: Implement impact function //------------------------------------------------------------------------------ void CBaseSDKBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity, bool bIsSecondary ) { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); //Do view kick AddViewKick(); //Make sound for the AI CSoundEnt::InsertSound( SOUND_BULLET_IMPACT, traceHit.endpos, 400, 0.2f, pPlayer ); // This isn't great, but it's something for when the crowbar hits. pPlayer->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART ); CBaseEntity *pHitEntity = traceHit.m_pEnt; //Apply damage to a hit target if ( pHitEntity != NULL ) { Vector hitDirection; pPlayer->EyeVectors( &hitDirection, NULL, NULL ); VectorNormalize( hitDirection ); CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB ); if( pPlayer && pHitEntity->IsNPC() ) { // If bonking an NPC, adjust damage. info.AdjustPlayerDamageInflictedForSkillLevel(); } CalculateMeleeDamageForce( &info, hitDirection, traceHit.endpos ); pHitEntity->DispatchTraceAttack( info, hitDirection, &traceHit ); ApplyMultiDamage(); // Now hit all triggers along the ray that... TraceAttackToTriggers( info, traceHit.startpos, traceHit.endpos, hitDirection ); if ( ToBaseCombatCharacter( pHitEntity ) ) { gamestats->Event_WeaponHit( pPlayer, !bIsSecondary, GetClassname(), info ); } } // Apply an impact effect ImpactEffect( traceHit ); }
void CMultiDamage::AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType ) { if( !pEntity ) return; m_bitsDamageTypes |= bitsDamageType; if( pEntity != m_pEntity ) { //TODO: replace this - Solokiller ApplyMultiDamage( CBaseEntity::Instance( pevInflictor ), CBaseEntity::Instance( pevInflictor ) ); // UNDONE: wrong attacker! m_pEntity = pEntity; m_flAmount = 0; } m_flAmount += flDamage; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pOther - //----------------------------------------------------------------------------- void CDODBaseRocket::RocketTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) ) return; if ( pOther->GetCollisionGroup() == COLLISION_GROUP_WEAPON ) return; // if we hit the skybox, just disappear const trace_t &tr = CBaseEntity::GetTouchTrace(); const trace_t *p = &tr; trace_t *newTrace = const_cast<trace_t*>(p); if( tr.surface.flags & SURF_SKY ) { UTIL_Remove( this ); return; } if( !pOther->IsPlayer() ) { CTakeDamageInfo info; info.SetAttacker( this ); info.SetInflictor( this ); info.SetDamage( 50 ); info.SetDamageForce( vec3_origin ); // don't worry about this not having a damage force. // It will explode on touch and impart its own forces info.SetDamageType( DMG_CLUB ); Vector dir; AngleVectors( GetAbsAngles(), &dir ); pOther->DispatchTraceAttack( info, dir, newTrace ); ApplyMultiDamage(); } if( pOther->IsAlive() ) { Explode(); } // else we will continue our movement }
// this function only gets called in multiplayer void CCrossbow::FireSniperBolt() { m_flNextPrimaryAttack = GetNextAttackDelay(0.75); if (m_iClip == 0) { PlayEmptySound( ); return; } TraceResult tr; m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME; m_iClip--; int flags; #if defined( CLIENT_WEAPONS ) flags = FEV_NOTHOST; #else flags = 0; #endif PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); Vector anglesAim = m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle; UTIL_MakeVectors( anglesAim ); Vector vecSrc = m_pPlayer->GetGunPosition( ) - gpGlobals->v_up * 2; Vector vecDir = gpGlobals->v_forward; UTIL_TraceLine(vecSrc, vecSrc + vecDir * 8192, dont_ignore_monsters, m_pPlayer->edict(), &tr); #ifndef CLIENT_DLL if ( tr.pHit->v.takedamage ) { ClearMultiDamage( ); CBaseEntity::Instance(tr.pHit)->TraceAttack(m_pPlayer->pev, 120, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB ); ApplyMultiDamage( pev, m_pPlayer->pev ); } #endif }
//------------------------------------------------------------------------------ // Purpose: Implement impact function //------------------------------------------------------------------------------ void CBaseHL2MPBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity ) { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); //Do view kick // AddViewKick(); CBaseEntity *pHitEntity = traceHit.m_pEnt; //Apply damage to a hit target if ( pHitEntity != NULL ) { Vector hitDirection; pPlayer->EyeVectors( &hitDirection, NULL, NULL ); VectorNormalize( hitDirection ); #ifndef CLIENT_DLL CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB ); if( pPlayer && pHitEntity->IsNPC() ) { // If bonking an NPC, adjust damage. info.AdjustPlayerDamageInflictedForSkillLevel(); } CalculateMeleeDamageForce( &info, hitDirection, traceHit.endpos ); pHitEntity->DispatchTraceAttack( info, hitDirection, &traceHit ); ApplyMultiDamage(); // Now hit all triggers along the ray that... TraceAttackToTriggers( info, traceHit.startpos, traceHit.endpos, hitDirection ); #endif //DHL - Skillet if ( pHitEntity->entindex() == 0 ) WeaponSound( MELEE_HIT_WORLD ); else WeaponSound( MELEE_HIT ); } // Apply an impact effect ImpactEffect( traceHit ); }
void CBeam::BeamDamage( TraceResult *ptr ) { RelinkBeam(); if ( ptr->flFraction != 1.0 && ptr->pHit != NULL ) { CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit); if ( pHit ) { ClearMultiDamage(); pHit->TraceAttack( pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM ); ApplyMultiDamage( pev, pev ); if ( pev->spawnflags & SF_BEAM_DECALS ) { if ( pHit->IsBSPModel() ) UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) ); } } } pev->dmgtime = gpGlobals->time; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBasePlasmaProjectile::MissileTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() ) return; // Create a plasma effect trace_t tr; Vector velDir = GetAbsVelocity(); VectorNormalize( velDir ); Vector vecSpot = GetLocalOrigin() - velDir * 32; // First, just clip to the box Ray_t ray; ray.Init( vecSpot, vecSpot + velDir * 64 ); enginetrace->ClipRayToEntity( ray, MASK_SHOT, pOther, &tr ); // Create the appropriate impact bool bHurtTarget = ( !InSameTeam( pOther ) && pOther->m_takedamage != DAMAGE_NO ); WeaponImpact( &tr, velDir, bHurtTarget, pOther, GetDamageType() ); #if !defined( CLIENT_DLL ) CBaseEntity *pOwner = m_hOwner; // Do damage (unless I'm explosive, in which case I'll do damage later) if ( m_flDamage && !m_flExplosiveRadius ) { ClearMultiDamage(); // Assume it's a projectile, so use its velocity instead Vector vecDamageOrigin = GetAbsVelocity(); VectorNormalize( vecDamageOrigin ); vecDamageOrigin = GetAbsOrigin() - (vecDamageOrigin * 32); CTakeDamageInfo info( this, pOwner, m_flDamage, m_DamageType ); CalculateBulletDamageForce( &info, GetAmmoDef()->Index("MediumRound"), GetAbsVelocity(), vecDamageOrigin ); pOther->DispatchTraceAttack( info, velDir, &tr ); ApplyMultiDamage(); } #endif Detonate(); }
//----------------------------------------------------------------------------- // Purpose: Damages anything in the beam. // Input : ptr - //----------------------------------------------------------------------------- void CBeam::BeamDamage( trace_t *ptr ) { RelinkBeam(); #if !defined( CLIENT_DLL ) if ( ptr->fraction != 1.0 && ptr->m_pEnt != NULL ) { CBaseEntity *pHit = ptr->m_pEnt; if ( pHit ) { ClearMultiDamage(); Vector dir = ptr->endpos - GetAbsOrigin(); VectorNormalize( dir ); int nDamageType = DMG_ENERGYBEAM; #ifndef HL1_DLL if (m_nDissolveType == 0) { nDamageType = DMG_DISSOLVE; } else if ( m_nDissolveType > 0 ) { nDamageType = DMG_DISSOLVE | DMG_SHOCK; } #endif CTakeDamageInfo info( this, this, m_flDamage * (gpGlobals->curtime - m_flFireTime), nDamageType ); CalculateMeleeDamageForce( &info, dir, ptr->endpos ); pHit->DispatchTraceAttack( info, dir, ptr ); ApplyMultiDamage(); if ( HasSpawnFlags( SF_BEAM_DECALS ) ) { if ( pHit->IsBSPModel() ) { UTIL_DecalTrace( ptr, GetDecalName() ); } } } } #endif m_flFireTime = gpGlobals->curtime; }
//----------------------------------------------------------------------------- // Purpose: Called when we've collided with another entity //----------------------------------------------------------------------------- void CTFFlameEntity::OnCollide( CBaseEntity *pOther ) { // remember that we've burnt this player m_hEntitiesBurnt.AddToTail( pOther ); float flDistance = GetAbsOrigin().DistTo( m_vecInitialPos ); float flMultiplier; if ( flDistance <= 125 ) { // at very short range, apply short range damage multiplier flMultiplier = tf_flamethrower_shortrangedamagemultiplier.GetFloat(); } else { // make damage ramp down from 100% to 60% from half the max dist to the max dist flMultiplier = RemapValClamped( flDistance, tf_flamethrower_maxdamagedist.GetFloat()/2, tf_flamethrower_maxdamagedist.GetFloat(), 1.0, 0.6 ); } float flDamage = m_flDmgAmount * flMultiplier; flDamage = max( flDamage, 1.0 ); if ( tf_debug_flamethrower.GetInt() ) { Msg( "Flame touch dmg: %.1f\n", flDamage ); } CBaseEntity *pAttacker = m_hAttacker; if ( !pAttacker ) return; SetHitTarget(); CTakeDamageInfo info( GetOwnerEntity(), pAttacker, GetOwnerEntity(), flDamage, m_iDmgType, TF_DMG_CUSTOM_BURNING ); info.SetReportedPosition( pAttacker->GetAbsOrigin() ); // We collided with pOther, so try to find a place on their surface to show blood trace_t pTrace; UTIL_TraceLine( WorldSpaceCenter(), pOther->WorldSpaceCenter(), MASK_SOLID|CONTENTS_HITBOX, this, COLLISION_GROUP_NONE, &pTrace ); pOther->DispatchTraceAttack( info, GetAbsVelocity(), &pTrace ); ApplyMultiDamage(); }
//----------------------------------------------------------------------------- // Purpose: // Input : // Output : //----------------------------------------------------------------------------- void CGrenade_Brickbat::BrickbatTouch( CBaseEntity *pOther ) { // ----------------------------------------------------------- // Might be physically simulated so get my velocity manually // ----------------------------------------------------------- Vector vVelocity; GetVelocity(&vVelocity,NULL); // ----------------------------------- // Do damage if we moving fairly fast // ----------------------------------- if (vVelocity.Length() > 100) { if (GetThrower()) { trace_t tr; tr = CBaseEntity::GetTouchTrace( ); ClearMultiDamage( ); Vector forward; AngleVectors( GetLocalAngles(), &forward ); CTakeDamageInfo info( this, GetThrower(), m_flDamage, DMG_CRUSH ); CalculateMeleeDamageForce( &info, forward, tr.endpos ); pOther->DispatchTraceAttack( info, forward, &tr ); ApplyMultiDamage(); } // If this thrown item explodes, blow it up if (m_bExplodes) { Detonate(); return; } } else if (pOther->GetFlags() & FL_CLIENT) { SpawnBrickbatWeapon(); return; } }
// 20mm cannon // self->nojumptime < - fixes the bh w/ 20mm bug void BigAssBullet ( vec3_t direction, float damage ) { vec3_t org, src, vtemp; makevectors( self->s.v.v_angle ); src[0] = self->s.v.origin[0] + ( g_globalvars.v_forward[0] * 10 ); src[1] = self->s.v.origin[1] + ( g_globalvars.v_forward[0] * 10 ); src[2] = self->s.v.absmin[2] + ( self->s.v.size[2] * 0.7 ); ClearMultiDamage ( ); VectorScale( direction, 1500, vtemp ); VectorAdd( vtemp, src, vtemp ); traceline( PASSVEC3( src ), PASSVEC3( vtemp ), 0, self ); //traceline( src, (src + (direction * 1500)), 0, self ); if ( g_globalvars.trace_fraction != 1 ) TraceAttack ( damage, direction ); if ( PROG_TO_EDICT( g_globalvars.trace_ent )->s.v.takedamage ) { org[0] = g_globalvars.trace_endpos[0] - ( g_globalvars.v_forward[0] * 4 ); org[1] = g_globalvars.trace_endpos[1] - ( g_globalvars.v_forward[1] * 4 ); org[2] = g_globalvars.trace_endpos[2] - ( g_globalvars.v_forward[2] * 4 ); //org = (trace_endpos - (v_forward * 4)); SpawnBlood ( org, 9 ); } else { //org = (trace_endpos - (v_forward * 4)); org[0] = g_globalvars.trace_endpos[0] - ( g_globalvars.v_forward[0] * 4 ); org[1] = g_globalvars.trace_endpos[1] - ( g_globalvars.v_forward[1] * 4 ); org[2] = g_globalvars.trace_endpos[2] - ( g_globalvars.v_forward[0] * 4 ); trap_WriteByte( MSG_BROADCAST, SVC_TEMPENTITY ); trap_WriteByte( MSG_BROADCAST, TE_SPIKE ); trap_WriteCoord( MSG_BROADCAST, org[0] ); trap_WriteCoord( MSG_BROADCAST, org[1] ); trap_WriteCoord( MSG_BROADCAST, org[2] ); trap_multicast( PASSVEC3( g_globalvars.trace_endpos ), MULTICAST_PHS ); } ApplyMultiDamage ( ); }
/* ================ FireBullets Used by shotgun, super shotgun, and enemy soldier firing Go to the trouble of combining multiple pellets into a single damage call. ================ */ void FireBullets( float shotcount, vec3_t dir, float spread_x, float spread_y, float spread_z ) { vec3_t direction; vec3_t src, tmp; makevectors( self->s.v.v_angle ); VectorScale( g_globalvars.v_forward, 10, tmp ); VectorAdd( self->s.v.origin, tmp, src ); //src = self->s.v.origin + v_forward*10; src[2] = self->s.v.absmin[2] + self->s.v.size[2] * 0.7; ClearMultiDamage(); traceline( PASSVEC3( src ), src[0] + dir[0] * 2048, src[1] + dir[1] * 2048, src[2] + dir[2] * 2048, false, self ); VectorScale( dir, 4, tmp ); VectorSubtract( g_globalvars.trace_endpos, tmp, puff_org ); // puff_org = trace_endpos - dir*4; while ( shotcount > 0 ) { VectorScale( g_globalvars.v_right, crandom() * spread_x, tmp ); VectorAdd( dir, tmp, direction ); VectorScale( g_globalvars.v_up, crandom() * spread_y, tmp ); VectorAdd( direction, tmp, direction ); // direction = dir + crandom()*spread[0]*v_right + crandom()*spread[1]*v_up; VectorScale( direction, 2048, tmp ); VectorAdd( src, tmp, tmp ); traceline( PASSVEC3( src ), PASSVEC3( tmp ), false, self ); if ( g_globalvars.trace_fraction != 1.0 ) TraceAttack( 4, direction ); shotcount = shotcount - 1; } ApplyMultiDamage(); Multi_Finish(); }
void FireSentryBulletsMTFL2( int shotcount, gedict_t * targ, float spread_x, float spread_y, float spread_z ) { vec3_t direction; vec3_t src; vec3_t dir, end, tmp; sgAimMTFL2( self, targ, src, dir ); ClearMultiDamage( ); VectorScale( dir, 2048, end ); VectorAdd( end, src, end ); traceline( PASSVEC3( src ), PASSVEC3( end ), 0, self ); VectorScale( dir, 4, puff_org ); VectorSubtract( g_globalvars.trace_endpos, puff_org, puff_org ); while ( shotcount > 0 ) { VectorScale( g_globalvars.v_right, crandom( ) * spread_x, tmp ); VectorScale( g_globalvars.v_up, crandom( ) * spread_y, direction ); VectorAdd( direction, tmp, direction ); VectorAdd( direction, dir, direction ); VectorNormalize( direction ); VectorScale( direction, 2048, end ); VectorAdd( end, src, end ); traceline( PASSVEC3( src ), PASSVEC3( end ), 0, self ); if ( g_globalvars.trace_fraction != 1 ) { TraceAttack( 4, direction ); } shotcount = shotcount - 1; } ApplyMultiDamage( ); Multi_Finish( ); }