CBlockBase *CWeaponCombatCannon::FindTraceBlock( void ) { CSDKPlayer *pPlayer = ToSDKPlayer( GetOwner() ); CBaseEntity *pEntity = NULL; if ( m_grabController.GetAttached() ) { pEntity = m_grabController.GetAttached(); } else { Vector vecSrc, vecEnd, vecDir; vecSrc = pPlayer->Weapon_ShootPosition(); pPlayer->EyeVectors( &vecDir ); // Calculate max distance as twice the radius of the block float max_distance = pPlayer->CollisionProp()->BoundingRadius() + lf_freeze_distance_combat.GetFloat(); vecEnd = vecSrc + vecDir * max_distance; UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT, GetOwner(), COLLISION_GROUP_NONE, &m_tr ); pEntity = m_tr.m_pEnt; } if ( !pEntity || !pEntity->IsBlock() ) { ResetFreezing(); return NULL; } CBlockBase *pBlock = dynamic_cast < CBlockBase * > ( pEntity ); if( !pBlock ) { DevMsg( "Not a block\n" ); return NULL; } return pBlock; }
//------------------------------------------------------------------------------ // Purpose: Implement impact function //------------------------------------------------------------------------------ void CWeaponSDKMelee::Hit( trace_t &traceHit, Activity nHitActivity ) { CSDKPlayer *pPlayer = ToSDKPlayer( 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 WeaponSound( MELEE_HIT ); } // Apply an impact effect ImpactEffect( traceHit ); }
//------------------------------------------------------------------------------ // Purpose : Starts the swing of the weapon and determines the animation // Input : bIsSecondary - is this a secondary attack? //------------------------------------------------------------------------------ void CWeaponSDKMelee::Swing( int bIsSecondary ) { trace_t traceHit; // Try a ray CSDKPlayer *pOwner = ToSDKPlayer( GetOwner() ); if ( !pOwner ) return; Vector swingStart = pOwner->Weapon_ShootPosition( ); Vector forward; pOwner->EyeVectors( &forward, NULL, NULL ); Vector swingEnd = swingStart + forward * GetRange(); UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit ); Activity nHitActivity = ACT_VM_HITCENTER; #ifndef CLIENT_DLL // Like bullets, melee traces have to trace against triggers. CTakeDamageInfo triggerInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB ); TraceAttackToTriggers( triggerInfo, traceHit.startpos, traceHit.endpos, vec3_origin ); #endif if ( traceHit.fraction == 1.0 ) { float meleeHullRadius = 1.732f * MELEE_HULL_DIM; // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point // Back off by hull "radius" swingEnd -= forward * meleeHullRadius; UTIL_TraceHull( swingStart, swingEnd, g_meleeMins, g_meleeMaxs, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit ); if ( traceHit.fraction < 1.0 && traceHit.m_pEnt ) { Vector vecToTarget = traceHit.m_pEnt->GetAbsOrigin() - swingStart; VectorNormalize( vecToTarget ); float dot = vecToTarget.Dot( forward ); // YWB: Make sure they are sort of facing the guy at least... if ( dot < 0.70721f ) { // Force amiss traceHit.fraction = 1.0f; } else { nHitActivity = ChooseIntersectionPointAndActivity( traceHit, g_meleeMins, g_meleeMaxs, pOwner ); } } } WeaponSound( SINGLE ); // ------------------------- // Miss // ------------------------- if ( traceHit.fraction == 1.0f ) { nHitActivity = bIsSecondary ? ACT_VM_MISSCENTER2 : ACT_VM_MISSCENTER; // We want to test the first swing again Vector testEnd = swingStart + forward * GetRange(); // See if we happened to hit water ImpactWater( swingStart, testEnd ); } else { Hit( traceHit, nHitActivity ); } // Send the anim SendWeaponAnim( nHitActivity ); //pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); //Setup our next attack times m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); }