[noob] The easiest way to hooking all collides - how to do it?

Hi
I try write my first useful lua plugin but i have many problems. This plugin should prevent from irresponsible players which lags server (spams props etc.).
My idea is that plugin should count number of collides for each entity in a given unit of time. If server will have fps drop - he will freeze entities with the biggest count of collides and kick/ban players which created/used them.
I think i know how to save count of collides in entity (Entity:SetVar) but i don’t know how to hook collides. I found interesting event: ENTITY:PhysicsCollide but, first, im not sure do i properly hook it.
First way:



function Collide( colData, collider ) 
	Msg("bleble")
end
hook.Add("PhysicsCollide", "physCol", Collide)


Second way:



function PhysicsCollide( colData, collider ) 
	Msg("bleble")
end


Looks like both doesn’t work (I spawn props, touch them together but in console nothing appear).
In old wiki, at “ENT.PhysicsCollide” I found:

I searched additional information about “Scripted Entities” and i found in old wiki:

But I tested my script for Bouncy Ball and doesn’t work too :frowning: Also i dont know how to convert normal entities to scripted entities (easy way).

What I am doing wrong? Help please.
Greg

PhysicsCollide is an ENTITY hook, not a gamemode hook. To log every single physics collide, you will have to add “PhysicsCollide” hook to each entity using the Entity:AddCallback function in something like OnEntityCreated hook.

Thanks for fast answer :slight_smile:
I created that script:



hook.Add("OnEntityCreated", "entityCreated", EntityCreated)
function EntityCreated( ent ) 
	Msg("Entity created
");
	ent:AddCallback("PhysicsCollide", onColide);
end

function onColide( ent ) 
	Msg("Collide!
");
end


Is it ok? Looks like it works but, i dont know why, i must load it 2x (i use lua_openscript command).

Put the hook.Add stuff AFTER you define the function you put into the hook.Add:



local function onColide( ent ) -- Localize this too, since we only use it from function below
    Msg("Collide!
");
end

local function EntityCreated( ent ) -- Make it local, we are not going to use this anywhere else, except for the line below
    Msg("Entity created
");
    ent:AddCallback("PhysicsCollide", onColide);
end
hook.Add("OnEntityCreated", "entityCreated", EntityCreated)



Or like this:
To save space, if you want




hook.Add("OnEntityCreated", "entityCreated", function( ent )
    Msg("Entity created
");
    ent:AddCallback("PhysicsCollide", function( self, data )
        Msg("Collide!
");
    end)
end)



Please note, that semicolons ( ; ) are optional in Lua.

Thanks again. Now i have next problem:



local function onColide ( colData, collider ) 
	Msg("Collide!
");
	Msg(collider:GetName())
	Msg("
")
end

local function EntityCreated( entity ) 
	Msg("Entity created
");
	entity:AddCallback("PhysicsCollide", onColide)
	Msg(entity:GetCreator())
	Msg("
")
end
hook.Add("OnEntityCreated", "entityCreated", EntityCreated)


The problem is that i can’t get collider’s name


[ERROR] lua/test.lua:3: attempt to call method 'GetName' (a nil value)

And can’t get Creator when entity is created, even when I spawn (return nil)
Tried also a few other methods and they don’t work too. What I am doing wrong?!

If collider isn’t a player you’ll get this error. Add :IsPlayer() check or something.
EDIT: I think it’ll never be player since it’s PhysObj of entity, not entity itself.

But problems is that other methods like GetMass() or GetEntity() doesn’t work too (probably other too). Error happens when method is called. Maybe something is wrong with ‘collider’ param. When I write it by ‘Msg’ i get table (look below)



local function onColide ( colData, collider ) 
	Msg("Collide!
")
	Msg(" collider = ", collider, "
")                                        //collider = table: 0x23e113b8
	Msg(" collider:GetName() = ", collider:GetName(), "
")      //attempt to call method 'GetName' (a nil value)
	Msg(" collider:GetMass() = ", collider:GetMass(), "
")        //attempt to call method 'GetMass' (a nil value)
	Msg(" collider:GetEntity() = ", collider:GetEntity(), "
")       //attempt to call method 'GetEntity' (a nil value)
	Msg("Done Collide!
");
end

local function EntityCreated( entity )
	entity:AddCallback("PhysicsCollide", onColide)
	Msg("Entity created!
")
	Msg(" entity = ", entity, "
")                                         //entity = Entity [67][prop_physics]
	Msg(" entity:GetCreator() = ", entity:GetCreator(), "
")  //entity:GetCreator() = nil

	Msg("Done entity create!
")
end
hook.Add("OnEntityCreated", "entityCreated", EntityCreated)


[editline]21st August 2014[/editline]

Wait wait… maybe in wiki is mistake and params are swapped?!

[editline]21st August 2014[/editline]



Msg(" colData = ", colData, "
") //colData = Entity [93][prop_physics]
Msg(" collider = ", collider, "
") //collider = table: 0x2b568968


[editline]21st August 2014[/editline]

If I think good this is wrong (http://wiki.garrysmod.com/page/ENTITY/PhysicsCollide):


ENTITY:PhysicsCollide( table colData, PhysObj collider )

And should be something like this:


ENTITY:PhysicsCollide( Entity collider, table colData )

Indeed it’s wrong, I just checked. Arguments are swapped and it passes Entity instead of PhysObj.
EDIT: I changed the wiki page. Not sure if it’s correct actually, this may be a bug. For now it still should be this way though.

Wasnt there a ShouldCollide gamemode hook he could use?

It is not wrong.

You are wrong because you are looking at a wiki page for ENT:PhysicsCollide hook, but you are using AddCallback, which is entirely different story.

Now I have next problem. I can’t send param (Entity) to function called by Timer:



local function RefreshPhysicsAttacker(ent)
	Msg(ent, "
") //nil
end

local function PhysgunPickup( ply, ent )
	Msg("Pick! ", ent, "
") //here is ok
	timer.Create( "PhysAttackRefr_" .. ent:GetCreationID(), 0.5, 0, RefreshPhysicsAttacker, ent )
end
hook.Add("PhysgunPickup", "GrzesioPhysgunPickup", PhysgunPickup)


[editline]21st August 2014[/editline]

Sorry about that. Soo how can i use ENT:PhysicsCollide hook? And where can i find function params using AddCallback?

that’s not how you use timers. You can’t use ENT:PhysicsCollide with prop_physics on engine entities, as said before. Just print out the parameters.

Ok I resolved problem with timer:


timer.Create( "PhysAttackRefr_" .. ent:GetCreationID(), 0.5, 0, function() RefreshPhysicsAttacker(ent) end )

I tested Bouncy Ball and it doesn’t work with AddCallback. If it is not engine entity, how I can hook its collision?

What do you mean?

Wrote this just for you: http://wiki.garrysmod.com/page/Entity_Callbacks

Thanks but, if I will have in future similator problem, still I don’t where/how search information. Sometimes they just don’t exists? Or just I dont know where/how search (for example that params)?

And still I don’t know how use all hooks (http://wiki.garrysmod.com/page/Category:Hooks) which are listed on wiki :frowning:

I’ve tried doing this except without saying the collide message, i had it remove itself, i did this with a sniper rifle of my design, however, it removes the thing I’m shooting at as well, and now whenever i try to spawn an entity other than my sniper bullet, it created errors, any help on this?