From ce19cde9b041ef43736b628ae8058bbc4598c6cc Mon Sep 17 00:00:00 2001 From: jhh8 Date: Thu, 27 Nov 2025 01:55:57 +0200 Subject: [PATCH 1/4] lasermine: revert 8aa91d6 --- .../shared/swarm/asw_weapon_laser_mines.cpp | 293 +++++++----------- .../shared/swarm/asw_weapon_laser_mines.h | 2 - 2 files changed, 120 insertions(+), 175 deletions(-) diff --git a/src/game/shared/swarm/asw_weapon_laser_mines.cpp b/src/game/shared/swarm/asw_weapon_laser_mines.cpp index 2d9ef778e..4a6d9afd1 100644 --- a/src/game/shared/swarm/asw_weapon_laser_mines.cpp +++ b/src/game/shared/swarm/asw_weapon_laser_mines.cpp @@ -111,26 +111,12 @@ void CASW_Weapon_Laser_Mines::PrimaryAttack( void ) { #ifdef CLIENT_DLL if ( !prediction->InPrediction() || prediction->IsFirstTimePredicted() ) -#endif { - Vector vecSrc = pMarine->GetAbsOrigin(); - vecSrc.z += 16.0f; // place lower to catch shorter aliens - Vector vecAiming = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187 - vecAiming.z = 0; - vecAiming.NormalizeInPlace(); - - const int nMinesPerShot = MarineSkills()->GetSkillBasedValueByMarine( pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_LASER_MINES ); - const float flSpread = 30.0f; // spread of mine throwing in degrees - - // try to predict whether mine throw is valid, if not then dont do the animation. - // small problem: this prediction happens a little earlier than the actual throw, so there will be occassional cases when the animation does play when it shouldnt have or it will not play when it should have. though still better than always playing imo. - if ( GetThrownMineCount( nMinesPerShot, vecSrc, vecAiming, flSpread ) > 0 ) - { - pMarine->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE ); - - EmitSound( "ASW_Mine.Throw" ); - } + pMarine->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE ); } +#else + pMarine->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE ); +#endif // start our delayed attack m_bShotDelayed = true; @@ -176,14 +162,125 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) for ( int i = 0; i < nMinesPerShot; i++ ) { - CBaseEntity *pParent = NULL; - trace_t tr; + // throw each mine out at a different angle + QAngle angRot = vec3_angle; Vector vecMineAiming = vecAiming; - - if ( !ValidateThrow( i, nMinesPerShot, vecSrc, vecAiming, flSpread, bOnGround, pParent, tr, vecMineAiming ) ) - continue; + angRot[ YAW ] = ( (float) i / (float) nMinesPerShot ) * flSpread - ( 0.5f * flSpread ); + VectorRotate( vecAiming, angRot, vecMineAiming ); + + // trace for a wall in front of the marine + const float flDeployDistance = 180.0f; + //if ( i != 1 ) // randomize all but the middle mine's distance slightly + //{ + //flDeployDistance += SharedRandomFloat( "LaserMineVariation", -20.0f, 20.0f ); + //} + trace_t tr; + + if ( !pMarine->IsInhabited() ) + { + bOnGround = true; +#ifndef CLIENT_DLL + + Vector vecDest = pMarine->m_vecOffhandItemSpot; + + vecDest.z += 16; + if ( i == 0 || i == 2 ) // drop to the side + { + Vector vecPerpendicular; + VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); + Vector vecNewDest = vecDest + vecPerpendicular * ( ( i == 0 ) ? 32 : -32 ); + UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides + if ( tr.startsolid ) + continue; + + if ( !tr.DidHit() ) + { + // trace down again + vecDest = vecNewDest; + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + } + } + else + { + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + } + if ( tr.startsolid ) + continue; + + if ( !tr.DidHit() ) + continue; +#endif + } + else + { + UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + + if ( tr.startsolid ) // if we started in solid, trace again from the marine's center + { + vecSrc.x = pMarine->WorldSpaceCenter().x; + vecSrc.y = pMarine->WorldSpaceCenter().y; + UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + if ( tr.startsolid ) + continue; + } + + if ( !tr.DidHit() ) + { + // do another trace to try and put it on the ground +#ifndef CLIENT_DLL + Vector vecDest = pPlayer->GetCrosshairTracePos(); + if ( vecDest.DistTo( vecSrc ) > flDeployDistance ) + { + trace_t tr2; + UTIL_TraceLine( tr.endpos, tr.endpos + Vector( 0, 0, -128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr2 ); + tr = tr2; + } + else + { + // just put it under the xhair + vecDest.z += 16; + if ( i == 0 || i == 2 ) // drop to the side + { + Vector vecPerpendicular; + VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); + Vector vecNewDest = vecDest + vecPerpendicular * ( ( i == 0 ) ? 32 : -32 ); + UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides + if ( tr.startsolid ) + continue; + + if ( !tr.DidHit() ) + { + // trace down again + vecDest = vecNewDest; + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + } + } + else + { + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + } + } + + if ( tr.startsolid ) + continue; + + if ( !tr.DidHit() ) + continue; +#endif + bOnGround = true; + } + } #ifndef CLIENT_DLL + CBaseEntity *pParent = NULL; + if ( tr.m_pEnt && !tr.m_pEnt->IsWorld() ) + { + pParent = tr.m_pEnt; + } + // no attaching to alien noses + if ( pParent && ( pParent->IsNPC() || pParent->Classify() == CLASS_ASW_STATUE ) ) + continue; + // calculate the laser aim offset relative to the mine facing QAngle angFacing, angLaser, angLaserOffset; VectorAngles( tr.plane.normal, angFacing ); @@ -198,8 +295,6 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) RotationDelta( angFacing, angLaser, &angLaserOffset ); CASW_Laser_Mine *pMine = CASW_Laser_Mine::ASW_Laser_Mine_Create( tr.endpos, angFacing, angLaserOffset, pMarine, pParent, true, this ); - pMine->m_vecSurfaceNormal = tr.plane.normal; - IGameEvent * event = gameeventmanager->CreateEvent( "laser_mine_placed" ); if ( event ) { @@ -235,154 +330,6 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) m_flNextPrimaryAttack = gpGlobals->curtime; } -bool CASW_Weapon_Laser_Mines::ValidateThrow( int nMineNumber, int nMinesPerShot, Vector vecSrc, Vector vecAiming, float flSpread, bool &bOnGround, CBaseEntity *pParent, trace_t &tr, Vector &vecMineAiming ) -{ - CASW_Player *pPlayer = GetCommander(); - if ( !pPlayer ) - return false; - - CASW_Marine *pMarine = GetMarine(); - if ( !pMarine || pMarine->GetWaterLevel() == 3 ) - return false; - - // throw each mine out at a different angle - QAngle angRot = vec3_angle; - angRot[ YAW ] = ( (float) nMineNumber / (float) nMinesPerShot ) * flSpread - ( 0.5f * flSpread ); - VectorRotate( vecAiming, angRot, vecMineAiming ); - - // trace for a wall in front of the marine - const float flDeployDistance = 180.0f; - //if ( i != 1 ) // randomize all but the middle mine's distance slightly - //{ - //flDeployDistance += SharedRandomFloat( "LaserMineVariation", -20.0f, 20.0f ); - //} - - if ( !pMarine->IsInhabited() ) - { - bOnGround = true; -#ifndef CLIENT_DLL - - Vector vecDest = pMarine->m_vecOffhandItemSpot; - - vecDest.z += 16; - if ( nMineNumber == 0 || nMineNumber == 2 ) // drop to the side - { - Vector vecPerpendicular; - VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); - Vector vecNewDest = vecDest + vecPerpendicular * ( ( nMineNumber == 0 ) ? 32 : -32 ); - UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides - if ( tr.startsolid ) - return false; - - if ( !tr.DidHit() ) - { - // trace down again - vecDest = vecNewDest; - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - } - } - else - { - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - } - if ( tr.startsolid ) - return false; - - if ( !tr.DidHit() ) - return false; -#endif - } - else - { - UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - - if ( tr.startsolid ) // if we started in solid, trace again from the marine's center - { - vecSrc.x = pMarine->WorldSpaceCenter().x; - vecSrc.y = pMarine->WorldSpaceCenter().y; - UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - if ( tr.startsolid ) - return false; - } - - if ( !tr.DidHit() ) - { - // do another trace to try and put it on the ground -//#ifndef CLIENT_DLL - Vector vecDest = pMarine->GetOffhandThrowDest(); - if ( vecDest.DistTo( vecSrc ) > flDeployDistance ) - { - trace_t tr2; - UTIL_TraceLine( tr.endpos, tr.endpos + Vector( 0, 0, -128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr2 ); - tr = tr2; - } - else - { - // just put it under the xhair - vecDest.z += 16; - if ( nMineNumber == 0 || nMineNumber == 2 ) // drop to the side - { - Vector vecPerpendicular; - VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); - Vector vecNewDest = vecDest + vecPerpendicular * ( ( nMineNumber == 0 ) ? 32 : -32 ); - UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides - if ( tr.startsolid ) - return false; - - if ( !tr.DidHit() ) - { - // trace down again - vecDest = vecNewDest; - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - } - } - else - { - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); - } - } - - if ( tr.startsolid ) - return false; - - if ( !tr.DidHit() ) - return false; -//#endif - bOnGround = true; - } - } - -//#ifndef CLIENT_DLL - if ( tr.m_pEnt && !tr.m_pEnt->IsWorld() ) - { - pParent = tr.m_pEnt; - } - // no attaching to alien noses - if ( pParent && (pParent->IsNPC() || pParent->Classify() == CLASS_ASW_STATUE) ) - return false; -//#endif - - return true; -} - -int CASW_Weapon_Laser_Mines::GetThrownMineCount( int nMinesPerShot, Vector vecSrc, Vector vecAiming, float flSpread ) -{ - int nThrown = 0; - - for ( int i = 0; i < nMinesPerShot; i++ ) - { - CBaseEntity *pParent = NULL; - trace_t tr; - Vector vecMineAiming = vecAiming; - bool bOnGround = false; - - if ( ValidateThrow( i, nMinesPerShot, vecSrc, vecAiming, flSpread, bOnGround, pParent, tr, vecMineAiming ) ) - nThrown++; - } - - return nThrown; -} - void CASW_Weapon_Laser_Mines::Precache() { BaseClass::Precache(); diff --git a/src/game/shared/swarm/asw_weapon_laser_mines.h b/src/game/shared/swarm/asw_weapon_laser_mines.h index 1591c05ea..105502a5f 100644 --- a/src/game/shared/swarm/asw_weapon_laser_mines.h +++ b/src/game/shared/swarm/asw_weapon_laser_mines.h @@ -30,8 +30,6 @@ class CASW_Weapon_Laser_Mines : public CASW_Weapon bool Reload(); void ItemPostFrame(); virtual bool ShouldMarineMoveSlow() { return false; } // firing mines doesn't slow the marine down - bool ValidateThrow( int nMineNumber, int nMinesPerShot, Vector vecSrc, Vector vecAiming, float flSpread, bool& bOnGround, CBaseEntity* pParent, trace_t& tr, Vector& vecMineAiming ); - int GetThrownMineCount( int nMinesPerShot, Vector vecSrc, Vector vecAiming, float flSpread ); Activity GetPrimaryAttackActivity( void ); From 0c4cc896d8b31d9efcdb38bd2dc0cee2c4a58ba5 Mon Sep 17 00:00:00 2001 From: jhh8 Date: Thu, 27 Nov 2025 01:58:50 +0200 Subject: [PATCH 2/4] lasermine: make throw trace ignore npcs, only look at world --- .../shared/swarm/asw_weapon_laser_mines.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game/shared/swarm/asw_weapon_laser_mines.cpp b/src/game/shared/swarm/asw_weapon_laser_mines.cpp index 4a6d9afd1..62e25de88 100644 --- a/src/game/shared/swarm/asw_weapon_laser_mines.cpp +++ b/src/game/shared/swarm/asw_weapon_laser_mines.cpp @@ -189,7 +189,7 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) Vector vecPerpendicular; VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); Vector vecNewDest = vecDest + vecPerpendicular * ( ( i == 0 ) ? 32 : -32 ); - UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides + UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); // trace out to the sides if ( tr.startsolid ) continue; @@ -197,12 +197,12 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) { // trace down again vecDest = vecNewDest; - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); } } else { - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); } if ( tr.startsolid ) continue; @@ -213,13 +213,13 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) } else { - UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); if ( tr.startsolid ) // if we started in solid, trace again from the marine's center { vecSrc.x = pMarine->WorldSpaceCenter().x; vecSrc.y = pMarine->WorldSpaceCenter().y; - UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecSrc, vecSrc + vecMineAiming * flDeployDistance, MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); if ( tr.startsolid ) continue; } @@ -232,7 +232,7 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) if ( vecDest.DistTo( vecSrc ) > flDeployDistance ) { trace_t tr2; - UTIL_TraceLine( tr.endpos, tr.endpos + Vector( 0, 0, -128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr2 ); + UTIL_TraceLine( tr.endpos, tr.endpos + Vector( 0, 0, -128 ), MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr2 ); tr = tr2; } else @@ -244,7 +244,7 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) Vector vecPerpendicular; VectorRotate( vecAiming, QAngle( 0, 90, 0 ), vecPerpendicular ); Vector vecNewDest = vecDest + vecPerpendicular * ( ( i == 0 ) ? 32 : -32 ); - UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); // trace out to the sides + UTIL_TraceLine( vecDest, vecNewDest, MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); // trace out to the sides if ( tr.startsolid ) continue; @@ -252,12 +252,12 @@ void CASW_Weapon_Laser_Mines::DelayedAttack( void ) { // trace down again vecDest = vecNewDest; - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); } } else { - UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_NONE, &tr ); + UTIL_TraceLine( vecDest, vecDest - Vector( 0, 0, 128 ), MASK_SOLID, pMarine, COLLISION_GROUP_DEBRIS, &tr ); } } From cd90509b607e7fcc61b0bfd0d5d27101ffaf8afe Mon Sep 17 00:00:00 2001 From: jhh8 Date: Thu, 27 Nov 2025 02:24:06 +0200 Subject: [PATCH 3/4] lasermine: make following parent's movement more correct --- src/game/server/swarm/asw_laser_mine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/server/swarm/asw_laser_mine.cpp b/src/game/server/swarm/asw_laser_mine.cpp index 2ae30f57a..3ed95fbcd 100644 --- a/src/game/server/swarm/asw_laser_mine.cpp +++ b/src/game/server/swarm/asw_laser_mine.cpp @@ -188,8 +188,8 @@ void CASW_Laser_Mine::SpawnFlipThink() { if ( !m_bIsSpawnLanded ) { - Vector vecVelStop( 0,0,0 ); - SetAbsVelocity( vecVelStop ); + CBaseEntity *pParent = GetMoveParent(); + SetAbsVelocity( pParent ? pParent->GetAbsVelocity() : Vector( 0, 0, 0 ) ); SetAbsOrigin( m_vecSpawnFlipEndPos ); From 75f787937d0f721770c7c753986c061258f141c9 Mon Sep 17 00:00:00 2001 From: jhh8 Date: Thu, 27 Nov 2025 16:05:53 +0200 Subject: [PATCH 4/4] formatting --- src/game/server/swarm/asw_laser_mine.cpp | 5 +---- src/game/shared/swarm/asw_weapon_laser_mines.cpp | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/game/server/swarm/asw_laser_mine.cpp b/src/game/server/swarm/asw_laser_mine.cpp index 3ed95fbcd..4c1e30adb 100644 --- a/src/game/server/swarm/asw_laser_mine.cpp +++ b/src/game/server/swarm/asw_laser_mine.cpp @@ -188,12 +188,9 @@ void CASW_Laser_Mine::SpawnFlipThink() { if ( !m_bIsSpawnLanded ) { - CBaseEntity *pParent = GetMoveParent(); - SetAbsVelocity( pParent ? pParent->GetAbsVelocity() : Vector( 0, 0, 0 ) ); - + SetLocalVelocity( vec3_origin ); SetAbsOrigin( m_vecSpawnFlipEndPos ); - QAngle angVel( 0, 0, 0 ); SetLocalAngularVelocity( angVel ); /* diff --git a/src/game/shared/swarm/asw_weapon_laser_mines.cpp b/src/game/shared/swarm/asw_weapon_laser_mines.cpp index 62e25de88..011723290 100644 --- a/src/game/shared/swarm/asw_weapon_laser_mines.cpp +++ b/src/game/shared/swarm/asw_weapon_laser_mines.cpp @@ -111,12 +111,10 @@ void CASW_Weapon_Laser_Mines::PrimaryAttack( void ) { #ifdef CLIENT_DLL if ( !prediction->InPrediction() || prediction->IsFirstTimePredicted() ) +#endif { pMarine->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE ); } -#else - pMarine->DoAnimationEvent( PLAYERANIMEVENT_THROW_GRENADE ); -#endif // start our delayed attack m_bShotDelayed = true;