GM:ShouldCollide()

I’m having real trouble with this function, the basic idea is that normal players should never collide with each other or npcs. While if admins have their physgun out, they collide with everyone so that they can grab players and npcs if needed.

The first IF was basically a fix so props stopped nocolliding with world…
But then all players started to collide with each other, and that’s a really bad problem when there are many players…

Code:
[lua]
function GM:ShouldCollide(entA, entB)
if entA && entB && ((!entA:IsPlayer() || !entB:IsPlayer()) || (!table.HasValue(GODLIKE_NPCS, entB:GetClass()) || !table.HasValue(FRIENDLY_NPCS, entB:GetClass())) || (!table.HasValue(GODLIKE_NPCS, entA:GetClass()) || !table.HasValue(FRIENDLY_NPCS, entA:GetClass()))) then
–This is basically my fix so props stops nocolliding with world of some reason after a set of time
return true
elseif entA && entB && (((entA:IsPlayer() && !entA:IsAdmin()) && ((entB:IsPlayer() && !entB:IsAdmin()) || table.HasValue(GODLIKE_NPCS, entB:GetClass()) || table.HasValue(FRIENDLY_NPCS, entB:GetClass()))) || ((entB:IsPlayer() && !entB:IsAdmin()) && ((entA:IsPlayer() && !entA:IsAdmin()) || table.HasValue(GODLIKE_NPCS, entA:GetClass()) || table.HasValue(FRIENDLY_NPCS, entA:GetClass())))) then
–Return false since it is a player
return false
elseif string.find(game.GetMap(), “d1_trainstation”) then
–Return true, only admins got weapons here…
return true
elseif entA && entB && ((entA:IsPlayer() && entA:IsAdmin() && entA:GetActiveWeapon():GetClass() != “weapon_physgun”) && (entB:IsPlayer() || table.HasValue(GODLIKE_NPCS, entB:GetClass()) || table.HasValue(FRIENDLY_NPCS, entB:GetClass())) || (entB:IsPlayer() && entB:IsAdmin() && entB:GetActiveWeapon():GetClass() != “weapon_physgun”) && (entA:IsPlayer() || table.HasValue(GODLIKE_NPCS, entA:GetClass()) || table.HasValue(FRIENDLY_NPCS, entA:GetClass()))) then
–Basic if you are not holding physgun code
return false
else
–Return true if you are holding physgun, or no code matched above.
return true
end
end
[/lua]

Don’t return true. That’s your problem. If you say return true as a blanket statement, everything collides with everything else which is bad.

So removing that else statement should fix it?

[lua]
–Removed that if at the first line since it is no longer useful if that was the problem
if entA && entB && (((entA:IsPlayer() && !entA:IsAdmin()) && ((entB:IsPlayer() && !entB:IsAdmin()) || table.HasValue(GODLIKE_NPCS, entB:GetClass()) || table.HasValue(FRIENDLY_NPCS, entB:GetClass()))) || ((entB:IsPlayer() && !entB:IsAdmin()) && ((entA:IsPlayer() && !entA:IsAdmin()) || table.HasValue(GODLIKE_NPCS, entA:GetClass()) || table.HasValue(FRIENDLY_NPCS, entA:GetClass())))) then
return false
elseif string.find(game.GetMap(), “d1_trainstation”) then
return true
elseif entA && entB && ((entA:IsPlayer() && entA:IsAdmin() && entA:GetActiveWeapon():GetClass() != “weapon_physgun”) && (entB:IsPlayer() || table.HasValue(GODLIKE_NPCS, entB:GetClass()) || table.HasValue(FRIENDLY_NPCS, entB:GetClass())) || (entB:IsPlayer() && entB:IsAdmin() && entB:GetActiveWeapon():GetClass() != “weapon_physgun”) && (entA:IsPlayer() || table.HasValue(GODLIKE_NPCS, entA:GetClass()) || table.HasValue(FRIENDLY_NPCS, entA:GetClass()))) then
return false
elseif entA && entB && ((entA:IsPlayer() && entA:IsAdmin() && entA:GetActiveWeapon():GetClass() == “weapon_physgun”) && (entB:IsPlayer() || table.HasValue(GODLIKE_NPCS, entB:GetClass()) || table.HasValue(FRIENDLY_NPCS, entB:GetClass())) || (entB:IsPlayer() && entB:IsAdmin() && entB:GetActiveWeapon():GetClass() == “weapon_physgun”) && (entA:IsPlayer() || table.HasValue(GODLIKE_NPCS, entA:GetClass()) || table.HasValue(FRIENDLY_NPCS, entA:GetClass()))) then
return true
end
[/lua]

Never return true in GM.ShouldCollide, either return false to not collide, or return nothing to collide.

Alright, so only keeping the return false ones solves the problem?

Edit: It did not fix the problem, if it is not returned, no player collides with anything, I have to return true in my function or it’ll not work…