Creating an Entity with a position based off another entity

Hello, so this is going to be the first post I create here, concerning my first addon I am inquiring about here / creating entirely.
Still pretty new to LUA with only vague prior coding experience and much more new to this forum and how things work, so if my code or conduct vexes anybody or breaks some unspoken rules: all I can say is “My bad.”

========================================================================================
I have created a vending machine entity that opens a GUI on the caller’s screen when used and presents a number of selection buttons, utilizing Net.Send / Net.Receive and all that fun stuff. GUI’s not the problem though.

As of now, the vending machine works but it presents a strange bug in that if you have more than one vending machine active in your game: the latest created one will override the spawn location of the products being created.

I’ll post the snippet of my code that has to do with setting the position of the item.
Please note: it is currently inside the ENT:USE function only because it improved the issue by having it only occur if two players are simultaneously using different machines. Originally, the product position was set inside of ENT:Initialize.
This is not a fix, and I am aware that it is not.

function ENT:Use(acti,call)

	net.Start("reservemachinemenu")
	net.Send(call)
	
	local Usesound = Sound(self.UseSound)

	if call:IsPlayer() then 
	self:EmitSound(self.UseSound, 60, 100, .5, CHAN_AUTO) -- Selection Menu opened.

		for k,v in pairs(Selections) do
	
	 		net.Receive(v, function()
				self:EmitSound(self.ButtonSound, 75, 102, 1, CHAN_AUTO) -- Selection made SFX

				timer.Simple(.35, function() 
	 				self:EmitSound("ProductFalling") -- SFX of item tumbling out of machine.
	 			end)

	 			local face = self:GetForward() 
	 			local product =	ents.Create(v)
	 			local name = self:GetForward() * -4
	 				name:Rotate(Angle(0,90,0)) 
	 			product:SetPos(self:GetPos() + (face*30) -Vector(0,0,32) + name)
	 			product:SetAngles(self:GetAngles() + Angle(0,0,90))
	 			product:SetCollisionGroup(COLLISION_GROUP_WEAPON)

				timer.Simple(0.8, function()   
	 				product:Spawn()
					product:GetPhysicsObject():SetMass(2)
					product:GetPhysicsObject():ApplyForceCenter(face*99)

				end)						
			end )
		end 
	end 
end 	

If there is any other part of my code anyone would wish to see, please ask and I can provide it if it is relevant.
Also if there are simply ways I can improve this code, I would be more than grateful to know as again I am still rather new and learning a lot.

Thank you for your time.

There is a lot going wrong with this code. For starters you are redefining a net.Receive for every selection, which is bad. That’s why it keeps updating with entities, because the ENT:Use is making a new receive. You will want that receive defined OUTSIDE OF A FUNCTION and then transmit the entity. Do some sanity checks for network security

An example here: net.Receive - Garry's Mod Wiki

Thanks for for getting back to me,

Fair enough, the code I have is the end product of trial and error until it doesn’t throw up errors in the console while writing what various tutorials said to do (this and that).

Knowing a little more now, I started rewriting it yesterday to ensure I make the right moves.

This is what I got so far in the cl_init. Outside of everything.

for k,v in pairs(NStrings) do
local button = vgui.Create(“DButton”,frame)
CreateButton(k,button)

		local can = Selections[k]

		function button:DoClick()
			if(!net.Start(v)) then net.Start(v) end 
					net.WriteInt(k,6)
					net.WriteString(string str)
				net.SendToServer()
				frame:Close()	
		end 
	end 

	function frame:Think() if (!LocalPlayer():Alive()) then if frame then frame:Remove() end end end 
	function frame:OnKeyCodePressed(key)
		if (key == KEY_END) then 
			frame:Remove() 
		end 		
	end 

========================================================================================

And this is what I have so far to test it in the server

for k , v in pairs(Selections) do
net.Receive(NStrings[k] , function()
local num = (net.ReadInt(6))
local cho = (net.ReadString())
print("The selection was choice " … num… ", " … cho)
end)
end

(I haven’t the slightest how the formatting on these posts go, sorry)

========================================================================================

One of the issues I had previously that lead me to erroneously placing this into the ENT metafunction was that I still am unsure how to reference my entity outside of “self” inside of its metafunctions.

Example being, when this message is recieved reads the proper string and ints, I want the entity to play a sound but I haven’t figured how to make ENT:EmitSound work here.

Thank you for your time.

Thanks for getting back to me.

Yeah, the wiki and this forum has been on my browser for about the entire journey here, sometimes in numbers up to 20 tabs.

I’ve made the blunder of being content that my latest edit to code made it “work” without knowing exactly what goes down when it’s ran. Hoping to prevent that from becoming a habit right now.

So I’m gonna just go put a big NEVERMIND on this particular “issue”.
Considering I learned it only took two words to solve the “self” issue, declaring ent outside of everything.

I feel inept.

You shouldn’t declare ent outside of everything. The suggestion I gave you was to send the entity they are using through the net message.

Basic questions boil down to one of these:

  1. Player presses E on a vending machine. How does he know what vending machine he pressed E on? What if he lags?
  2. Person sends an order to the server. How does the server know what vending machine should process the order?

The step after is to do your sanity checks. Does this net message make sense? Are they allowed to do what they are asking to do? ETC. These are the core things to consider when doing any networking, otherwise you create security vulnerabilities.

Trying to not spoon feed you this as I have faith you can figure this out on your own ( plus you’ll never forget it if you do :stuck_out_tongue: )

I really do appreciate that, and the time you’ve taken to get back to me.

Will come back triumphant or at least a little bit closer to it.

(Original post had wrong image)

Here goes,
I did this from scratch and it puts more stock into net messaging.

SERVER

CLIENT

I am unsure if I need to set the location on another back and forth between CLIENT and SERVER when the CLIENT sends the button message, have not tried debugging this with a second player yet.

And while I feel more confident in this code, I still believe I have made errors and/or it could be done more effeciently.

EDIT*
Just for information: The table at the bottom of the init is to keep track of all the things spawned by the machine so they may be deleted if you remove it: prevent clutter.