• Controlling SEnts with Derma windows?
    8 replies, posted
I'm attempting to make a Derma control panel for a nice little SEnt I'm working on. However, I've come across my old nemesis, the SERVER/CLIENT divide. So, my question is: How can I get a Derma window (over on the client) to get constantly-updated info from a SEnt (over on the server)? At the moment, I have the SEnt call up the window with: [lua] function ENT:Use( ply ) if self.NextUse < CurTime() then self.NextUse = CurTime() + 1 umsg.Start( "RDAHubWindow" ) umsg.Entity(self.Entity) umsg.End() end end [/lua] And in an autorun script: [lua] function HubWindow( data ) local hub = data:ReadEntity() Wmain = vgui.Create( "DFrame" ) Lres = vgui.Create( "DLabel", Wmain ) local WmainXw, WmainYw = 400, 400 Wmain:SetPos( (ScrW()-WmainXw)/2, (ScrH()-WmainYw)/2 ) Wmain:SetSize( WmainXw, WmainYw ) Wmain:SetTitle( hub.SysName.." System" ) Wmain:SetVisible( true ) Wmain:MakePopup() local s="" for res, amt in pairs( hub.Resources ) do s = s..res.."="..amt.." " end Lres:SetText( "Resources: "..s ) Lres:SetSize( 170, 20 ) Lres:SetPos( 20, 40 ) end usermessage.Hook( "RDAHubWindow", HubWindow ) [/lua] The problem is that the Derma window gets nil for hub.SysName, hub.Resources, and so forth - it can't see hub's data. How can I make this work? Additionally, I want to update the text of Lres once per second. How would one go about updating a Derma window? I'm a newb to Derma, in case it wasn't obvious.
If you put[B][I] print(hub)[/I][/B] in your HubWindow function does it print the entity or NULL? Are hub.SysName, hub.Resources definitely set on the client? (use: [B][I]lua_run_cl print(Entity(<whatever>).Resources)[/I][/B] to check) Is the entity in your PVS? (can you see it). If the entity is ever likely to be outside your PVS and you still need updates from it you'll probably want to set (serveride)... [B][I]function ENT:UpdateTransmitState() return TRANSMIT_ALWAYS end[/I][/B] To update the text, set the panels think function to update the text via [B][I]self.Lres:SetText( str )[/I][/B] and set the nextThink for 1 second.
print(hub) in HubWindow prints an entity. (Only because hub was sent by the SEnt's usermessage) print(hub.SysName) in HubWindow gives a nil. lua_run_cl print(Entity(<whatever>).Resources) gives a nil. I can see the entity ingame (and I can spawn it from the Entities tab). I don't think that having the SEnt's important variables on the client would be a good idea in this case. However, would it be possible to make client-side variables which mirrored the server-side ones? Panels have a think()? Would I invoke that with "function HubWindow:Think()"?
[QUOTE=Taehl;19048070]I don't think that having the SEnt's important variables on the client would be a good idea in this case. However, would it be possible to make client-side variables which mirrored the server-side ones? Panels have a think()? Would I invoke that with "function HubWindow:Think()"?[/QUOTE] If you're not sending the variables to the client how can you expect them to read them? Use SetNWVar, that's what it's for, mirrors the ents variable on the client. Server... [i][b]ent:SetNWInt( 'Resources', 9001 )[/i][/b] Client / Server... [i][b]resources = ent:GetNWInt( 'Resources' )[/i][/b] Valid types are: Int, Float, String, Bool, Angle, Vector, Entity For examples of a panel's think function, check out pretty much any derma control.
Very useful, thank you, but... Is there no SetNWTable? If not, how can I send an arbitrarily-sized table* this way? Also, can a client SetNWVar, or only Get? EDIT) I tried it, using a NWBool to try to turn the Hub and and off. No dice. It seems that a client using SetNWBool doesn't actually send anything to the server. So... How can I make a DButton affect my SEnt? *For example: [lua]hub.Resources = { ["Energy"]=122, ["Air"]=45, ["Water"]=3 }[/lua] Or even more complex: [lua]pump.Gains = { ["Energy"] = {[entity37]=18, [entity41]=0}, ["Air"] = {[entity37]=0, [entity41]=10} }[/lua]
There /must/ be a way to send variables from client to server. Has to be. How can I send a bool or string from Derma to my SEnt?
Console Commands & cvars is the only way. Check out how the tool weapon does it. You can also use datastream, but that uses concommands and also sends un-needed confirmation usermessages back from the server, so isn't very efficient.
-snip- Didn't read >.<
Console commands... So, I could do something like this (pseudocode)?[lua] Button.DoClick = function( hub, password ) consolecommand( "ToggleHub "..hub.." "..password ) end Hub.Toggle = function( hub, password ) if hub ~= self then return end if password ~= self.password then return end [code to toggle the Hub] end consolecommand.Hook( "ToggleHub", Toggle ) [/lua]
Sorry, you need to Log In to post a reply to this thread.