Skip to content

Commit 34e0d17

Browse files
committed
random assortment of gameplay fixes
1 parent cd09724 commit 34e0d17

File tree

5 files changed

+113
-24
lines changed

5 files changed

+113
-24
lines changed

game/server/tf/tf_obj_sentrygun.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,9 +2002,12 @@ int CObjectSentrygun::OnTakeDamage( const CTakeDamageInfo &info )
20022002
flDamage *= 1.0 - m_flHeavyBulletResist;
20032003
newInfo.SetDamage( flDamage );
20042004
}
2005+
2006+
int iPierceResists = 0;
2007+
CALL_ATTRIB_HOOK_INT_ON_OTHER( info.GetWeapon(), iPierceResists, mod_pierce_resists_absorbs );
20052008

20062009
// If we are shielded due to player control, we take less damage.
2007-
bool bFullyShielded = ( m_nShieldLevel > 0 ) && !HasSapper() && !IsPlasmaDisabled();
2010+
const bool bFullyShielded = !iPierceResists && ( m_nShieldLevel > 0 ) && !HasSapper() && !IsPlasmaDisabled();
20082011
if ( bFullyShielded )
20092012
{
20102013
float flDamage = newInfo.GetDamage();
@@ -2013,7 +2016,7 @@ int CObjectSentrygun::OnTakeDamage( const CTakeDamageInfo &info )
20132016
}
20142017

20152018
// Check to see if we are being sapped.
2016-
if ( HasSapper() )
2019+
if ( !iPierceResists && HasSapper() )
20172020
{
20182021
// Get the sapper owner.
20192022
CBaseObject *pSapper = GetObjectOfTypeOnMe( OBJ_ATTACHMENT_SAPPER );

game/shared/tf/tf_gamerules.cpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5476,12 +5476,17 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
54765476
CBaseEntity *pInflictor = dmgInfo->GetInflictor();
54775477

54785478
// Check that the explosion can 'see' this entity.
5479-
Vector vecSpot = pEntity->BodyTarget( vecSrc, false );
5479+
//std::vector<Vector> vecSpots{pEntity->EyePosition(), pEntity->WorldSpaceCenter(), pEntity->GetAbsOrigin()};
5480+
std::vector<Vector> vecSpots{pEntity->EyePosition()};
5481+
static const float flInnerRadiusPct = 0.05f;
54805482
CTraceFilterIgnorePlayers filterPlayers( pInflictor, COLLISION_GROUP_PROJECTILE );
54815483
CTraceFilterIgnoreFriendlyCombatItems filterCombatItems( pInflictor, COLLISION_GROUP_PROJECTILE, pInflictor->GetTeamNumber() );
54825484
CTraceFilterChain filter( &filterPlayers, &filterCombatItems );
5483-
5484-
UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
5485+
Vector vecOffset;
5486+
int totalChecks = 1;
5487+
int passedChecks = 0;
5488+
Vector vecMainSpot = pEntity->BodyTarget(vecSrc, false);
5489+
UTIL_TraceLine( vecSrc, vecMainSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
54855490
if ( tr.startsolid && tr.m_pEnt )
54865491
{
54875492
// Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
@@ -5490,12 +5495,48 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
54905495

54915496
filterPlayers.SetPassEntity( tr.m_pEnt );
54925497
CTraceFilterChain filterSelf( &filterPlayers, &filterCombatItems );
5493-
UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr );
5498+
UTIL_TraceLine( vecSrc, vecMainSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr );
54945499
}
5495-
5496-
// If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5500+
// If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked, so do a more robust check
54975501
if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
5498-
return 0;
5502+
{
5503+
for (int x = -1; x <= 1; x += 2)
5504+
{
5505+
vecOffset.x = x * flInnerRadiusPct;
5506+
for (int y = -1; y <= 1; y += 2)
5507+
{
5508+
vecOffset.y = y * flInnerRadiusPct;
5509+
for (int z = -1; z <= 1; z += 2)
5510+
{
5511+
vecOffset.z = z * flInnerRadiusPct;
5512+
for ( auto& vecSpot : vecSpots )
5513+
{
5514+
UTIL_TraceLine( vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
5515+
if ( tr.startsolid && tr.m_pEnt )
5516+
{
5517+
// Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
5518+
if ( tr.m_pEnt->IsCombatItem() && pEntity->InSameTeam( tr.m_pEnt ) && ( pEntity != tr.m_pEnt ) )
5519+
return 0;
5520+
5521+
filterPlayers.SetPassEntity( tr.m_pEnt );
5522+
CTraceFilterChain filterSelf( &filterPlayers, &filterCombatItems );
5523+
UTIL_TraceLine( vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr );
5524+
}
5525+
5526+
totalChecks++;
5527+
// If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5528+
if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
5529+
return 0;
5530+
passedChecks++;
5531+
}
5532+
}
5533+
}
5534+
}
5535+
}
5536+
else
5537+
{
5538+
passedChecks++;
5539+
}
54995540

55005541
// Adjust the damage - apply falloff.
55015542
float flAdjustedDamage = 0.0f;
@@ -5538,6 +5579,9 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
55385579
}
55395580
}
55405581

5582+
// As a compromise, reduce the damage if we only did it on a robust check
5583+
flAdjustedDamage *= passedChecks / (float) totalChecks;
5584+
55415585
// If we end up doing 0 damage, exit now.
55425586
if ( flAdjustedDamage <= 0 )
55435587
return 0;
@@ -5553,7 +5597,7 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
55535597
CTakeDamageInfo adjustedInfo = *dmgInfo;
55545598
adjustedInfo.SetDamage( flAdjustedDamage );
55555599

5556-
Vector dir = vecSpot - vecSrc;
5600+
Vector dir = vecMainSpot - vecSrc;
55575601
VectorNormalize( dir );
55585602

55595603
// If we don't have a damage force, manufacture one
@@ -6147,7 +6191,7 @@ bool CTFGameRules::ApplyOnDamageModifyRules( CTakeDamageInfo &info, CBaseEntity
61476191
// Use defense buffs if it's not a backstab or direct crush damage (telefrage, etc.)
61486192
if ( pVictim && info.GetDamageCustom() != TF_DMG_CUSTOM_BACKSTAB && ( info.GetDamageType() & DMG_CRUSH ) == 0 )
61496193
{
6150-
if ( pVictim->m_Shared.InCond( TF_COND_DEFENSEBUFF ) )
6194+
if ( !iPierceResists && pVictim->m_Shared.InCond( TF_COND_DEFENSEBUFF ) )
61516195
{
61526196
// We take no crits of any kind...
61536197
if( eBonusEffect == kBonusEffect_MiniCrit || eBonusEffect == kBonusEffect_Crit )
@@ -16437,7 +16481,7 @@ bool CTFGameRules::PlayerMayBlockPoint( CBasePlayer *pPlayer, int iPointIndex, c
1643716481
#endif
1643816482

1643916483
// Invuln players can block points
16440-
if ( pTFPlayer->m_Shared.IsInvulnerable() )
16484+
if ( pTFPlayer->m_Shared.IsInvulnerable() || pTFPlayer->m_Shared.InCond( TF_COND_MEGAHEAL ) )
1644116485
{
1644216486
if ( pszReason )
1644316487
{

game/shared/tf/tf_weapon_bottle.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,11 @@ void CTFStickBomb::Smack( void )
166166
{
167167
Vector vecForward;
168168
AngleVectors( pTFPlayer->EyeAngles(), &vecForward );
169-
Vector vecSwingStart = pTFPlayer->Weapon_ShootPosition();
169+
Vector vecCenter = pTFPlayer->WorldSpaceCenter();
170+
Vector vecSwingStart = pTFPlayer->Weapon_ShootPosition();
170171
Vector vecSwingEnd = vecSwingStart + vecForward * GetSwingRange();
171172

172-
Vector explosion = vecSwingStart;
173+
Vector explosion = vecCenter;
173174

174175
CPVSFilter filter( explosion );
175176

@@ -191,7 +192,7 @@ void CTFStickBomb::Smack( void )
191192
if ( IsCurrentAttackACrit() )
192193
dmgType |= DMG_CRITICAL;
193194

194-
CTakeDamageInfo info( pTFPlayer, pTFPlayer, this, explosion, explosion, 75.0f, dmgType, TF_DMG_CUSTOM_STICKBOMB_EXPLOSION, &explosion );
195+
CTakeDamageInfo info( pTFPlayer, pTFPlayer, this, vec3_origin, explosion, 75.0f, dmgType, TF_DMG_CUSTOM_STICKBOMB_EXPLOSION, &explosion );
195196
CTFRadiusDamageInfo radiusinfo( &info, explosion, 100.f );
196197
TFGameRules()->RadiusDamage( radiusinfo );
197198
}

game/shared/tf/tf_weapon_grenade_pipebomb.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "takedamageinfo.h"
3333
#include "tf_team.h"
3434
#include "physics_collisionevent.h"
35+
#include "vcollide.h"
36+
#include "vcollide_parse.h"
3537
#ifdef TF_RAID_MODE
3638
#include "player_vs_environment/boss_alpha/boss_alpha.h"
3739
#endif // TF_RAID_MODE
@@ -492,7 +494,8 @@ CTFGrenadePipebombProjectile* CTFGrenadePipebombProjectile::Create( const Vector
492494
//-----------------------------------------------------------------------------
493495
void CTFGrenadePipebombProjectile::Spawn()
494496
{
495-
if ( HasStickyEffects() )
497+
const bool bHasStickyEffects = HasStickyEffects();
498+
if ( bHasStickyEffects )
496499
{
497500
// Set this to max, so effectively they do not self-implode.
498501

@@ -526,6 +529,27 @@ void CTFGrenadePipebombProjectile::Spawn()
526529

527530
BaseClass::Spawn();
528531

532+
// Reset vphysics model but keep the material
533+
if ( !bHasStickyEffects && m_iType == TF_GL_MODE_CANNONBALL )
534+
{
535+
solid_t solid;
536+
PhysModelParseSolid( solid, this, GetModelIndex() );
537+
VPhysicsDestroyObject();
538+
int surfaceProp = -1;
539+
if ( solid.surfaceprop[0] )
540+
{
541+
surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop );
542+
}
543+
IPhysicsObject *pPhysicsObject = PhysModelCreate( this, modelinfo->GetModelIndex( TF_WEAPON_PIPEGRENADE_MODEL ), GetAbsOrigin(), GetAbsAngles(), NULL );
544+
pPhysicsObject->SetMaterialIndex(surfaceProp);
545+
if ( pPhysicsObject )
546+
{
547+
VPhysicsSetObject( pPhysicsObject );
548+
SetMoveType( MOVETYPE_VPHYSICS );
549+
pPhysicsObject->Wake();
550+
}
551+
}
552+
529553
m_bTouched = false;
530554
m_flCreationTime = gpGlobals->curtime;
531555

game/shared/tf/tf_weaponbase_melee.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ void CTFWeaponBaseMelee::Smack( void )
749749
#ifdef GAME_DLL
750750
for( int i=0; i<m_potentialVictimVector.Count(); ++i )
751751
{
752-
if ( m_potentialVictimVector[i] != NULL && m_potentialVictimVector[i]->IsAlive() )
752+
if ( m_potentialVictimVector[i] == NULL || !m_potentialVictimVector[i]->IsAlive() )
753753
{
754754
bIsCleanMiss = false;
755755
break;
@@ -820,13 +820,30 @@ void CTFWeaponBaseMelee::DoMeleeDamage( CBaseEntity* ent, trace_t& trace, float
820820
CALL_ATTRIB_HOOK_INT( iCritFromBehind, crit_from_behind );
821821
if ( iCritFromBehind > 0 )
822822
{
823-
Vector entForward;
824-
AngleVectors( ent->EyeAngles(), &entForward );
825-
826-
Vector toEnt = ent->GetAbsOrigin() - pPlayer->GetAbsOrigin();
827-
toEnt.NormalizeInPlace();
828-
829-
if ( DotProduct( toEnt, entForward ) > 0.7071f )
823+
// Get a vector from owner origin to target origin
824+
Vector vecToTarget;
825+
vecToTarget = ent->WorldSpaceCenter() - pPlayer->WorldSpaceCenter();
826+
vecToTarget.z = 0.0f;
827+
vecToTarget.NormalizeInPlace();
828+
829+
// Get owner forward view vector
830+
Vector vecOwnerForward;
831+
AngleVectors( pPlayer->EyeAngles(), &vecOwnerForward );
832+
vecOwnerForward.z = 0.0f;
833+
vecOwnerForward.NormalizeInPlace();
834+
835+
// Get target forward view vector
836+
Vector vecTargetForward;
837+
AngleVectors( ent->EyeAngles(), &vecTargetForward );
838+
vecTargetForward.z = 0.0f;
839+
vecTargetForward.NormalizeInPlace();
840+
841+
// Make sure owner is behind, facing and aiming at target's back
842+
float flPosVsTargetViewDot = DotProduct( vecToTarget, vecTargetForward ); // Behind?
843+
float flPosVsOwnerViewDot = DotProduct( vecToTarget, vecOwnerForward ); // Facing?
844+
float flViewAnglesDot = DotProduct( vecTargetForward, vecOwnerForward ); // Facestab?
845+
846+
if ( flPosVsTargetViewDot > 0.f && flPosVsOwnerViewDot > 0.5 && flViewAnglesDot > -0.3f )
830847
{
831848
iDmgType |= DMG_CRITICAL;
832849
}

0 commit comments

Comments
 (0)