NPC OnUse

So I’m creating a NPC, in witch it opens a menu when you talk to him/her. However, nothing happens. I think that the problem is the hook… since I didn’t add one. The reason is, I have no idea how. I’ve read the hook article on the wiki, and the tutorial here on Facepunch, yet I don’t know what to do, mainly because the tutorials there use things that you can find on the wiki.

[lua]
function npcmenu()

local sheet = vgui.Create( "DPropertySheet" );
sheet:SetSize( 300, 300 );

local panel = vgui.Create( "DPanel" );

local item1 = vgui.Create( "DLabel", panel );
item:SetText( "Label 1" );
item:SizeToContents( );

local item2 = vgui.Create( "DLabel", panel );
item2:SetText( "Label 2" );
item2:SizeToContents( );

sheet:AddSheet( “Out labels”, panel, nil, false, false, “Two labels” );

end

concommand.Add( “npc_test_menu”, npcmenu )

function ENT:Use( activator, caller )

LocalPlayer():ConCommand ( "npc_test_menu" )

end
[/lua]

So yea, help would be appreciated, and perhaps some additional explanation on hooks… ( Reason that I might not get it, cause I’m bad at maths and physics etc)

ENT:Use is a server-side function.
I’ve not worked with npcs yet but try this in the shared file.
[lua]if CLIENT then
function npcmenu()

	local sheet = vgui.Create( "DPropertySheet" );
	sheet:SetSize( 300, 300 );

	local panel = vgui.Create( "DPanel" );

	local item1 = vgui.Create( "DLabel", panel );
	item:SetText( "Label 1" );
	item:SizeToContents( );

	local item2 = vgui.Create( "DLabel", panel );
	item2:SetText( "Label 2" );
	item2:SizeToContents( );

sheet:AddSheet( "Out labels", panel, nil, false, false, "Two labels" );
 
end

usermessage.Hook( "npc_test_menu", npcmenu )

else
function ENT:Use( activator, caller )
if not activator:IsPlayer() then return end
umsg.Start(“npc_test_menu”,activator);umsg.End()

end

end[/lua]

ENT.Use isn’t called on SNPCs by default. To change that you can check for the “use”-input in ENT.AcceptInput:
[lua]if CLIENT then
function npcmenu()
local sheet = vgui.Create(“DPropertySheet”)
sheet:SetSize(300, 300)

	local panel = vgui.Create("DPanel")
	
	local item1 = vgui.Create("DLabel", panel)
	item:SetText("Label 1")
	item:SizeToContents()
	
	local item2 = vgui.Create("DLabel", panel)
	item2:SetText("Label 2")
	item2:SizeToContents()
	
	sheet:AddSheet("Out labels", panel, nil, false, false, "Two labels")
end
usermessage.Hook("npc_test_menu", npcmenu)

else
function ENT:Use(entActivator, entCaller)
if !entActivator:IsPlayer() then return end
umsg.Start(“npc_test_menu”,entActivator)
umsg.End()
end

function ENT:Initialize()
	self:SetUseType(3)
end

function ENT:AcceptInput(input, entActivator, entCaller, data)
	if string.lower(input) == "use" then
		self:Use(entActivator,entCaller)
		return
	end
end

end[/lua]

Why to use self:SetUseType(3), when it would be better to use self:SetUseType(SIMPLE_USE)?

Also, don’t you need to set the position of the property sheet or have some way to close it? It’s fine that it’s not parented to a frame, but if you don’t want it to screw up you need to use sheet:SetPos as well as provide a button to close it.

Thanks everyone, eventually silverlans worked :smiley:

So, anyone willing to explain how hooks exactly work. When to use em etc?

Hooks allow you to schedule a function to be run whenever something specific happens.
…So you should use them when you want a function to be run whenever you want something specific to happen.

Example:
[lua]local function playerDeath(ply, weap, killer)
print(ply:Nick() … " has died!")
end
hook.Add(“PlayerDeath”, “uniquename”, playerDeath)[/lua]

This will be called whenever GM.PlayerDeath is called, which is when a player dies.

There are four types of hooks, and only one of them can external scripts hook into.
There are Gamemode Hooks, which are the main set of things like players connecting, players dying etc. If you are writing a gamemode then you write hooks with function GM:HookName(params) end.
For anything else, you hook into them with hook.Add.


You should only ever return a value in a hook added with hook.Add when you specifically want to override all other hooks and the gamemode function

The other hooks are Weapon, Entity and Effect. Those hooks are specific to the scripted weapon/entity/effect that you are using them in, and you have to use them to get the weapon/entity/effect to behave differently to the base.

Right, I think i get it now,

[lua]hook.Add(“Pre-Defined name”, “name what you want it to be”, fucntion name)[lua]

Also offtopic

Learning a bit more about sheets/labels, since I couldn’t do that before. Only now I wanted to make a frame around it, but first of all the frame is off the spot( so it’s not at center, but the top-left corner is )

And there spawn 5 of em for some reason… Also when I close em all, the sheet doesn’t close
[lua] function npcmenu()

	local frame = vgui.Create("DFrame")
	frame:Center()
	frame:MakePopup()
	frame:SetSize(325, 325)
	frame:SetTitle( "Hello" )
	frame:SetDraggable( false )
	
	local sheet = vgui.Create("DPropertySheet")
	sheet:SetSize(300, 300)
	sheet:MakePopup()
	sheet:Center()
	sheet:SetParent("frame")
	
	local panel = vgui.Create("DPanel")
	
	local item1 = vgui.Create("DLabel", panel)
	item1:SetText("Label 1")
	item1:SizeToContents()
	
	local item2 = vgui.Create("DLabel", panel)
	item2:SetText("Label 2")
	item2:SizeToContents()
	
	sheet:AddSheet("Out labels", panel, nil, false, false, "Two labels")
end
usermessage.Hook("npc_test_menu", npcmenu)[/lua]

I don’t know if it makes a difference, but I would set the size of the frame before you center it.

Also, when you use SetParent, you parent to the panel object, not a string. So it would just be:


sheet:SetParent(frame)

Thanks, both does things you said, work. Only problem is that there still spawn loads of frames…

You’re trying to parent the DPropertySheet to a string, replace “frame” with frame. Next time read the information on the wiki. That solves your property sheet stays open question.

Yea, sorry about that.

One final question about panels: I’ve looked at other gamemodes to see how they did stuff. And I noticed that most gamemodes use Function Panel:Init. What is the difference between Panel:Init and local panel = vgui.create?