garrysmod-issues
garrysmod-issues copied to clipboard
VPhysics objects with collision group COLLISION_GROUP_PROJECTILE trigger grace period on humanoid NPCs, preventing ENT:PhysicsCollide()
Details
Branch: Only tested on x86-x64
A physics entity set to the projectile collision group triggers "grace" or otherwise known as invincibility frames to humanoid NPCs to any other physics entity of this collision group. This prevents ENT:PhysicsCollide() lua code from running at all.
SOLID_VPHYSICS, MOVETYPE_VPHYSICS, SetSolid SOLID_VPHYSICS
Example video: https://youtu.be/xtQ1ya2KAkc
Steps to reproduce
Set a physics entity's collision group to COLLISION_GROUP_PROJECTILE and hit any humanoid-based NPCs with more than one in a short period of time.
Easiest to test with making a weapon fire multiple physics objects like a shotgun.
After some more messing around while working, it would appear this actually applies to a lot of entities & not just humanoid NPCs. I wonder what makes other certain NPCs exempt from this now.
edit: I found a workaround for anyone who might be running into this problem in the event this ends up being something that can't be worked in natively.
I just slapped a table with enough information to be the collision data of PhysicsCollide inside of my entity's :Touch() function which calls PhysicsCollide.
Cannot reproduce.
Code for projectile:
AddCSLuaFile()
ENT.Base = "base_anim"
function ENT:PhysicsCollide( data, phys )
print( CurTime(), data.HitEntity, phys )
self:Remove()
end
function ENT:Initialize()
-- We do NOT want to execute anything below in this FUNCTION on CLIENT
if ( CLIENT ) then return end
-- Use the helibomb model just for the shadow (because it's about the same size)
self:SetModel( "models/props_junk/PopCan01a.mdl" )
self:SetCollisionGroup( COLLISION_GROUP_PROJECTILE )
self:PhysicsInit( SOLID_VPHYSICS )
self:PhysWake()
end
Code for the gun:
AddCSLuaFile()
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
function SWEP:PrimaryAttack()
self:SetNextPrimaryFire( CurTime() + 0.1 )
if ( CLIENT ) then return end
for i = 0, 6 do
local ent = ents.Create( "sent_ball" )
if ( !IsValid( ent ) ) then return end
local Forward = self.Owner:GetAimVector()
ent:SetPos( self.Owner:GetShootPos() + Forward * 32 + VectorRand( -10, 10 ) )
ent:SetAngles( self.Owner:EyeAngles() )
ent:SetOwner( self.Owner )
ent:Spawn()
ent:Activate()
ent:GetPhysicsObject():SetVelocity( Forward * 2000 )
ent:GetPhysicsObject():SetMass( 1 )
end
end
I've run into what I assume is the same issue. I've attached a way to recreate it using some code from Zombie Survival. This weapon sends out several projectiles that get removed when PhysicsCollide is called. In some instances, the projectile does not call PhysicsCollide for the prop, bounces off the prop as a result, then calls PhysicsCollide when it hits the ground instead.
https://youtu.be/_SLnvXKBY80
I do not see any "grace period" in relation to COLLISION_GROUP_PROJECTILE, from my look around, the callback is just not called from the physics engine. Why is anyones guess.