Is it possible to make a brush entity that responses to +use and prevents players from moving past?

I’ve been looking around for information on making a func_ brush entity spawnable in Hammer that responds to +use, and I’m also interested in if it can serve as a player clip as well. I can successfully make it function as a trigger, but using the ENT:Use hook and various physics flags fails to make the prop usable or solid to players.

Any help?

Well it’s definitely possible. 90% of what can be done in hammer can be done with Lua, the 10% being replicating BSP geometry and… water.

As far as I know, your best bet would be to use the KeyPress hook and use

util.IntersectRayWithOBB to detect if the player’s eye trace is intersecting with your brush while it isn’t solid.

For collisions, you’ll want to use PhysicsInitBox, or even just use SetModel on it. Calling :Activate() on the entity will force it to adopt the model’s collision bounds.
Be wary though, as I did it for my elevator tool and the game does not like it when it tries to draw the physgun/context halo for your brush.

To get the model of your brush to actually appear, you’ll need to create a separate prop_dynamic and set the model to the same thing, then parent it.

EDIT:

also, set the movetype of your brush entity to MOVETYPE_PUSH


AddCSLuaFile()

ENT.Base  = "base_entity"
ENT.Type  = "brush"

function ENT:Initialize()
  self.min   = Vector(self:WorldSpaceAABB()[1], self:WorldSpaceAABB()[2], self:WorldSpaceAABB()[3]);
  self.max   = Vector(self:WorldSpaceAABB()[4], self:WorldSpaceAABB()[5], self:WorldSpaceAABB()[6]);
  self:PhysicsInitBox(self.min, self.max);
  self:SetCollisionBounds(self.min, self.max);
  self:SetMoveType(MOVETYPE_PUSH);
end


This is from func_breakable_barrier.lua, which is spawning without errors. I’m focusing on making it solid to players first, which it still isn’t doing. I’ve been googling with no avail. :frowning:

Have you tried changing your entity’s solid type? Perhaps you’re doing that elsewhere in your code, but from what you gave, I don’t see you doing
[lua]self:SetSolid(SOLID_VPHYSICS)[/lua] anywhere.
Try some of the different SOLID_ enums, maybe one of them will work.

The reason I didn’t do that is because of what’s on the Wiki for PhysicsInitBox:

I will call it manually and see if other enums work. BBOX and VPHYSICS did nothing when I tried it early this morning.

[editline]8th August 2016[/editline]

None of the ENUMS work :frowning:


AddCSLuaFile();

ENT.Base  = "base_entity";
ENT.Type  = "brush";

function ENT:Initialize()
  self.min, self.max, self.center = self:OBBMins(), self:OBBMaxs(), self:OBBCenter();
  self:PhysicsInitBox(self.min, self.max);
  self:SetSolid(SOLID_VPHYSICS);
  self:SetCollisionBounds(self.min, self.max);
  self:SetMoveType(MOVETYPE_PUSH);
end

This didn’t work, no matter what I tried. I decided to try another approach with PhysicsFromMesh, which also doesn’t work:


AddCSLuaFile();

ENT.Base  = "base_entity";
ENT.Type  = "brush";

function ENT:Initialize()
  local function ReturnVertices(min, max)
    local vertices = {
      { pos = min },
      { pos = Vector(max.x, min.y, min.z) },
      { pos = Vector(max.x, max.y, min.z) },
      { pos = Vector(min.x, max.y, min.z) },
      { pos = Vector(min.x, min.y, max.z) },
      { pos = Vector(max.x, min.y, max.z) },
      { pos = Vector(max.x, max.y, max.z) },
      { pos = Vector(min.x, max.y, max.z) }
    }
    return vertices;
  end

  local min, max = self:OBBMins(), self:OBBMaxs();

  local vertices = ReturnVertices(min, max);
  PrintTable(vertices);
  self:PhysicsFromMesh(vertices);
  self:EnableCustomCollisions(true);
  self:SetSolid(SOLID_BBOX);
  self:SetMoveType(MOVETYPE_PUSH);
end

function ENT:Think()
end

Then I suppose your entity will have to be of type “anim” and not “brush”
I know Silverlan’s Wrench Toolset uses “anim” for making brushes, so perhaps he found that the “brush” type doesn’t work.

Welp, apparently ENT:Initialize() only calls on the client when I switch it to anim.

This works for me, what I’m currently using for creating a solid block entity using a mesh:


	self:PhysicsInit(SOLID_CUSTOM)
	self:SetMoveType(MOVETYPE_PUSH)
	self:SetSolid(SOLID_VPHYSICS)
	self:PhysicsFromMesh( self:RebuildMesh(true) )
	self:EnableCustomCollisions(true)

The only difference from your code is self:PhysicsInit(SOLID_CUSTOM) , and I am also doing the same thing clientside/shared, not sure if that matters. And of course rendering the mesh clientside.

EDIT:
This is with
[lua]ENT.Base = “base_anim”
ENT.Type = “anim”[/lua]

What is RebuildMesh? That’s not on the Wiki.

It seems that’s creating something solid, but weirdly offset at 0,0,0 or something. I’m going to move my map and see what’s going on.

EDIT: Yeah, something solid is being created at 0,0,0, but I can walk up diagonally from one side. I believe it created a triangle.


AddCSLuaFile();

ENT.Base  = "base_entity";
ENT.Type  = "anim";

function ENT:Initialize()

  local function ReturnVertices(min, max)
    local vertices = {
      { pos = min },
      { pos = Vector(max.x, min.y, min.z) },
      { pos = Vector(max.x, max.y, min.z) },
      { pos = Vector(min.x, max.y, min.z) },
      { pos = Vector(min.x, min.y, max.z) },
      { pos = Vector(max.x, min.y, max.z) },
      { pos = Vector(max.x, max.y, max.z) },
      { pos = Vector(min.x, max.y, max.z) }
    }
    return vertices;
  end

  local min, max = self:OBBMins(), self:OBBMaxs();

  local vertices = ReturnVertices(min, max);

  self:PhysicsInit(SOLID_CUSTOM);
  self:SetMoveType(MOVETYPE_PUSH);
  self:SetSolid(SOLID_VPHYSICS);
  self:PhysicsFromMesh(vertices);
  self:EnableCustomCollisions(true)
end

function ENT:Think()
end


Rebuildmesh is just my version of your returnvertices function.

I’ll post the source in a moment.

If you guys want to mess around with the vmf and bsp (which is super basic), you can grab them from my Dropbox
https://dl.dropboxusercontent.com/u/965202/facepunch/lua/garrysmod_test.bsp
https://dl.dropboxusercontent.com/u/965202/facepunch/lua/garrysmod_test.vmf

This is my RebuildMesh function. It just builds a cube. If the first parameter is true then it will return the vertices (what you need for PhysicsFromMesh), otherwise it will return an actual mesh (needed for rendering). It could definitely be a lot shorter but I like to be obvious with my variable naming for things like this.

In the code I use GetBlockBuilderMins/GetBlockBuilderMaxs which are functions I added, but using OBBMins/Maxs should be the same. Mins/Maxs should be relative to the entity.

Well, that function definitely does a lot better than what I did - it’s no longer a triangle! It’s still at 0,0,0 though.

Not sure. I had an issue with it rendering at 0,0,0 which I fixed by using PushModelMatrix before drawing it. But if the physics mesh ends up at 0,0,0 try adding your entities position to each of the verts.

I checked for the entity’s position during initialization, which just happened to be Vector(0, 0, 0). If I were to check for the position with brush as the type, it would report the correct vector. It’s really weird.

[editline]8th August 2016[/editline]

I’ve come to the conclusion that I’m actually not creating a functioning mesh, but instead creating an error. I realized this because I forgot to change “base_entity” to “base_anim”, which shows that I’m indeed creating an entity with the error model.

[editline]8th August 2016[/editline]


AddCSLuaFile();

ENT.Base  = "base_entity";
ENT.Type  = "brush";

function ENT:Initialize()
  self:PhysicsInit(SOLID_CUSTOM);
  self:SetMoveType(MOVETYPE_NONE);
  self:SetSolid(SOLID_VPHYSICS);
  self:EnableCustomCollisions(true);
  self:GetPhysicsObject():EnableMotion(false);
end

function ENT:Think()


If I remove the line for GetPhysicsObjects, it seems like something solid is in the right place, but I can seemingly move it around or make it disappear completely. Disabling motion just causes it to no longer be solid.

[editline]8th August 2016[/editline]


AddCSLuaFile();

ENT.Base  = "base_entity";
ENT.Type  = "brush";

function ENT:Initialize()
  self:PhysicsInit(SOLID_VPHYSICS);
  self:SetMoveType(MOVETYPE_NONE);
  self:SetSolid(SOLID_VPHYSICS);
  self:GetPhysicsObject():EnableMotion(false);
end

function ENT:Think()
end


This seems to be functioning properly - it’s solid now! I had to disable motion to prevent it from flipping out as I also changed the brush to clip through the wall a bit.

Also, making it solid also has made the entire thing work with plain old eyetraces:

https://dl.dropboxusercontent.com/u/965202/ShareX/2016/08/2016-08-08_15-36-49.png

I opened up an issue since brush based SENTs don’t seem to respond to +use. In the meantime, I think I might rewrite the entire use system for my gamemode - is there a way to manually trigger the OnUse hook on an entity?

[lua]entity:Use(activator, caller, useType, 1)[/lua]

?