Advertisement
Guest User

Untitled

a guest
Oct 15th, 2016
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.47 KB | None | 0 0
  1.  
  2. local meta = FindMetaTable( "Entity" )
  3.  
  4. -- Return if there's nothing to add on to
  5. if ( !meta ) then return end
  6.  
  7. AccessorFunc( meta, "m_bPlayPickupSound", "ShouldPlayPickupSound" )
  8.  
  9. --
  10. -- Entity index accessor. This used to be done in engine, but it's done in Lua now because it's faster
  11. --
  12. function meta:__index( key )
  13.  
  14. --
  15. -- Search the metatable. We can do this without dipping into C, so we do it first.
  16. --
  17. local val = meta[ key ]
  18. if ( val != nil ) then return val end
  19.  
  20. --
  21. -- Search the entity table
  22. --
  23. local tab = self:GetTable()
  24. if ( tab ) then
  25. local val = tab[ key ]
  26. if ( val != nil ) then return val end
  27. end
  28.  
  29. --
  30. -- Legacy: sometimes use self.Owner to get the owner.. so lets carry on supporting that stupidness
  31. -- This needs to be retired, just like self.Entity was.
  32. --
  33. if ( key == "Owner" ) then return meta.GetOwner( self ) end
  34.  
  35. return nil
  36.  
  37. end
  38.  
  39. --[[---------------------------------------------------------
  40. Name: Short cut to add entities to the table
  41. -----------------------------------------------------------]]
  42. function meta:GetVar( name, default )
  43.  
  44. local Val = self:GetTable()[ name ]
  45. if ( Val == nil ) then return default end
  46.  
  47. return Val
  48.  
  49. end
  50.  
  51. if ( SERVER ) then
  52.  
  53. function meta:SetCreator( ply )
  54. self.m_PlayerCreator = ply
  55. end
  56.  
  57. function meta:GetCreator()
  58. return self.m_PlayerCreator
  59. end
  60.  
  61. end
  62.  
  63. --[[---------------------------------------------------------
  64. Name: Returns true if the entity has constraints attached to it
  65. -----------------------------------------------------------]]
  66. function meta:IsConstrained()
  67.  
  68. if ( CLIENT ) then return self:GetNWBool( "IsConstrained" ) end
  69.  
  70. local c = self:GetTable().Constraints
  71. local bIsConstrained = false
  72.  
  73. if ( c ) then
  74.  
  75. for k, v in pairs( c ) do
  76. if ( IsValid( v ) ) then bIsConstrained = true break end
  77. c[ k ] = nil
  78. end
  79.  
  80. end
  81.  
  82. self:SetNWBool( "IsConstrained", bIsConstrained )
  83. return bIsConstrained
  84.  
  85. end
  86.  
  87. --[[---------------------------------------------------------
  88. Name: Short cut to set tables on the entity table
  89. -----------------------------------------------------------]]
  90. function meta:SetVar( name, value )
  91.  
  92. self:GetTable()[ name ] = value
  93.  
  94. end
  95.  
  96. --[[---------------------------------------------------------
  97. Name: CallOnRemove
  98. Desc: Call this function when this entity dies.
  99. Calls the function like Function( <entity>, <optional args> )
  100. -----------------------------------------------------------]]
  101. function meta:CallOnRemove( name, func, ... )
  102.  
  103. local mytable = self:GetTable()
  104. mytable.OnDieFunctions = mytable.OnDieFunctions or {}
  105.  
  106. mytable.OnDieFunctions[ name ] = { Name = name, Function = func, Args = { ... } }
  107.  
  108. end
  109.  
  110. --[[---------------------------------------------------------
  111. Name: RemoveCallOnRemove
  112. Desc: Removes the named hook
  113. -----------------------------------------------------------]]
  114. function meta:RemoveCallOnRemove( name )
  115.  
  116. local mytable = self:GetTable()
  117. mytable.OnDieFunctions = mytable.OnDieFunctions or {}
  118. mytable.OnDieFunctions[ name ] = nil
  119.  
  120. end
  121.  
  122. --[[---------------------------------------------------------
  123. Simple mechanism for calling the die functions.
  124. -----------------------------------------------------------]]
  125. local function DoDieFunction( ent )
  126.  
  127. if ( !ent || !ent.OnDieFunctions ) then return end
  128.  
  129. for k, v in pairs( ent.OnDieFunctions ) do
  130.  
  131. -- Functions aren't saved - so this could be nil if we loaded a game.
  132. if ( v && v.Function ) then
  133.  
  134. v.Function( ent, unpack( v.Args ) )
  135.  
  136. end
  137.  
  138. end
  139.  
  140. end
  141.  
  142. hook.Add( "EntityRemoved", "DoDieFunction", DoDieFunction )
  143.  
  144. function meta:PhysWake()
  145.  
  146. local phys = self:GetPhysicsObject()
  147. if ( !IsValid( phys ) ) then return end
  148.  
  149. phys:Wake()
  150.  
  151. end
  152.  
  153. function meta:GetChildBones( bone )
  154.  
  155. local bonecount = self:GetBoneCount()
  156. if ( bonecount == 0 || bonecount < bone ) then return end
  157.  
  158. local bones = {}
  159.  
  160. for k = 0, bonecount - 1 do
  161. if ( self:GetBoneParent( k ) != bone ) then continue end
  162. table.insert( bones, k )
  163. end
  164.  
  165. return bones
  166.  
  167. end
  168.  
  169. function meta:InstallDataTable()
  170.  
  171. self.dt = {}
  172. local datatable = {}
  173. local keytable = {}
  174. local meta = {}
  175. local editing = {}
  176.  
  177. meta.__index = function ( ent, key )
  178.  
  179. local dt = datatable[ key ]
  180. if ( dt == nil ) then return end
  181.  
  182. return dt.GetFunc( self, dt.index, key )
  183.  
  184. end
  185.  
  186. meta.__newindex = function( ent, key, value )
  187.  
  188. local dt = datatable[ key ]
  189. if ( dt == nil ) then return end
  190.  
  191. dt.SetFunc( self, dt.index, value )
  192.  
  193. end
  194.  
  195. self.DTVar = function( ent, typename, index, name )
  196.  
  197. local SetFunc = ent[ "SetDT" .. typename ]
  198. local GetFunc = ent[ "GetDT" .. typename ]
  199.  
  200. if ( !SetFunc || !GetFunc ) then
  201. MsgN( "Couldn't addvar " , name, " - type ", typename," is invalid!" )
  202. return
  203. end
  204.  
  205. datatable[ name ] = {
  206. index = index,
  207. SetFunc = SetFunc,
  208. GetFunc = GetFunc,
  209. typename = typename,
  210. Notify = {}
  211. }
  212.  
  213. return datatable[ name ]
  214.  
  215. end
  216.  
  217. --
  218. -- Access to the editing table
  219. --
  220. self.GetEditingData = function()
  221. return editing
  222. end
  223.  
  224. --
  225. -- Adds an editable variable.
  226. --
  227. self.SetupEditing = function( ent, name, keyname, data )
  228.  
  229. if ( !data ) then return end
  230.  
  231. if ( !data.title ) then data.title = name end
  232.  
  233. editing[ keyname ] = data
  234.  
  235. end
  236.  
  237. self.SetupKeyValue = function( ent, keyname, type, setfunc, getfunc, other_data )
  238.  
  239. keyname = keyname:lower()
  240.  
  241. keytable[ keyname ] = {
  242. KeyName = keyname,
  243. Set = setfunc,
  244. Get = getfunc,
  245. Type = type
  246. }
  247.  
  248. if ( other_data ) then
  249.  
  250. table.Merge( keytable[ keyname ], other_data )
  251.  
  252. end
  253.  
  254. end
  255.  
  256. local CallProxies = function( ent, tbl, name, oldval, newval )
  257.  
  258. for k, v in pairs( tbl ) do
  259. v( ent, name, oldval, newval )
  260. end
  261.  
  262. end
  263.  
  264. self.NetworkVar = function( ent, typename, index, name, other_data )
  265.  
  266. local t = ent.DTVar( ent, typename, index, name )
  267.  
  268. ent[ "Set" .. name ] = function( self, value )
  269. CallProxies( ent, t.Notify, name, self.dt[ name ], value )
  270. self.dt[ name ] = value
  271. end
  272.  
  273. ent[ "Get" .. name ] = function( self )
  274. return self.dt[ name ]
  275. end
  276.  
  277. if ( !other_data ) then return end
  278.  
  279. -- This KeyName stuff is absolutely unnecessary, there's absolutely no reason for it to exist
  280. -- But we cannot remove it now because dupes will break. It should've used the "name" variable
  281. if ( other_data.KeyName ) then
  282. ent:SetupKeyValue( other_data.KeyName, typename, ent[ "Set" .. name ], ent[ "Get" .. name ], other_data )
  283. ent:SetupEditing( name, other_data.KeyName, other_data.Edit )
  284. end
  285.  
  286. end
  287.  
  288. --
  289. -- Add a function that gets called when the variable changes
  290. -- Note: this doesn't work on the client yet - which drastically reduces its usefulness.
  291. --
  292. self.NetworkVarNotify = function( ent, name, func )
  293.  
  294. if ( !datatable[ name ] ) then error( "calling NetworkVarNotify on missing network var " .. name ) end
  295.  
  296. table.insert( datatable[ name ].Notify, func )
  297.  
  298. end
  299.  
  300. --
  301. -- Create an accessor of an element. This is mainly so you can use spare
  302. -- network vars (vectors, angles) to network single floats.
  303. --
  304. self.NetworkVarElement = function( ent, typename, index, element, name, other_data )
  305.  
  306. ent.DTVar( ent, typename, index, name, keyname )
  307.  
  308. ent[ "Set" .. name ] = function( self, value )
  309. local old = self.dt[ name ]
  310. old[ element ] = value
  311. self.dt[ name ] = old
  312. end
  313.  
  314. ent[ "Get" .. name ] = function( self )
  315. return self.dt[ name ][ element ]
  316. end
  317.  
  318. if ( !other_data ) then return end
  319.  
  320. -- This KeyName stuff is absolutely unnecessary, there's absolutely no reason for it to exist
  321. -- But we cannot remove it now because dupes will break. It should've used the "name" variable
  322. if ( other_data.KeyName ) then
  323. ent:SetupKeyValue( other_data.KeyName, "float", ent[ "Set" .. name ], ent[ "Get" .. name ], other_data )
  324. ent:SetupEditing( name, other_data.KeyName, other_data.Edit )
  325. end
  326.  
  327. end
  328.  
  329. self.SetNetworkKeyValue = function( self, key, value )
  330.  
  331. key = key:lower()
  332.  
  333. local k = keytable[ key ]
  334. if ( !k ) then return end
  335.  
  336. local v = util.StringToType( value, k.Type )
  337. if ( v == nil ) then return end
  338.  
  339. k.Set( self, v )
  340. return true
  341.  
  342. end
  343.  
  344. self.GetNetworkKeyValue = function( self, key )
  345.  
  346. key = key:lower()
  347.  
  348. local k = keytable[ key ]
  349. if ( !k ) then return end
  350.  
  351. return k.Get( self )
  352.  
  353. end
  354.  
  355. --
  356. -- Called by the duplicator system to get the network vars
  357. --
  358. self.GetNetworkVars = function( ent )
  359.  
  360. local dt = {}
  361.  
  362. for k, v in pairs( datatable ) do
  363.  
  364. -- Don't try to save entities (yet?)
  365. if ( v.typename == "Entity" ) then continue end
  366.  
  367. dt[ k ] = v.GetFunc( ent, v.index )
  368.  
  369. end
  370.  
  371. --
  372. -- If there's nothing in our table - then return nil.
  373. --
  374. if ( table.Count( dt ) == 0 ) then return nil end
  375.  
  376. return dt
  377.  
  378. end
  379.  
  380. --
  381. -- Called by the duplicator system to restore from network vars
  382. --
  383. self.RestoreNetworkVars = function( ent, tab )
  384.  
  385. if ( !tab ) then return end
  386.  
  387. -- Loop this entities data table
  388. for k, v in pairs( datatable ) do
  389.  
  390. -- If it contains this entry
  391. if ( tab[ k ] == nil ) then continue end
  392.  
  393. -- Set it.
  394. if ( ent[ "Set" .. k ] ) then
  395. ent[ "Set" .. k ]( ent, tab[ k ] )
  396. else
  397. v.SetFunc( ent, v.index, tab[k] )
  398. end
  399.  
  400. end
  401.  
  402. end
  403.  
  404. setmetatable( self.dt, meta )
  405.  
  406. --
  407. -- In sandbox the client can edit certain values on certain entities
  408. -- we implement this here incase any other gamemodes want to use it
  409. -- although it is of course deactivated by default.
  410. --
  411.  
  412. --
  413. -- This function takes a keyname and a value - both strings.
  414. --
  415. --
  416. -- Called serverside it will set the value.
  417. --
  418. self.EditValue = function( self, variable, value )
  419.  
  420. if ( !isstring( variable ) ) then return end
  421. if ( !isstring( value ) ) then return end
  422.  
  423. --
  424. -- It can be called clientside to send a message to the server
  425. -- to request a change of value.
  426. --
  427. if ( CLIENT ) then
  428.  
  429. net.Start( "editvariable" )
  430. net.WriteUInt( self:EntIndex(), 32 )
  431. net.WriteString( variable )
  432. net.WriteString( value )
  433. net.SendToServer()
  434.  
  435. end
  436.  
  437. --
  438. -- Called serverside it simply changes the value
  439. --
  440. if ( SERVER ) then
  441.  
  442. self:SetNetworkKeyValue( variable, value )
  443.  
  444. end
  445.  
  446. end
  447.  
  448. if ( SERVER ) then
  449.  
  450. util.AddNetworkString( "editvariable" )
  451.  
  452. net.Receive( "editvariable", function( len, client )
  453.  
  454. local iIndex = net.ReadUInt( 32 )
  455. local ent = Entity( iIndex )
  456.  
  457. if ( !IsValid( ent ) ) then return end
  458. if ( !isfunction( ent.GetEditingData ) ) then return end
  459. if ( ent.AdminOnly && !client:IsAdmin() ) then return end
  460.  
  461. local key = net.ReadString()
  462.  
  463. -- Is this key in our edit table?
  464. local editor = ent:GetEditingData()[ key ]
  465. if ( !istable( editor ) ) then return end
  466.  
  467. local val = net.ReadString()
  468. hook.Run( "VariableEdited", ent, client, key, val, editor )
  469.  
  470. end )
  471.  
  472. end
  473.  
  474. end
  475.  
  476. if ( SERVER ) then
  477.  
  478. AccessorFunc( meta, "m_bUnFreezable", "UnFreezable" )
  479.  
  480. end
  481.  
  482. --
  483. -- Networked var proxies
  484. --
  485. function meta:SetNetworkedVarProxy( name, func )
  486.  
  487. if ( !self.NWVarProxies ) then
  488. self.NWVarProxies = {}
  489. end
  490.  
  491. self.NWVarProxies[ name ] = func
  492.  
  493. end
  494.  
  495. function meta:GetNetworkedVarProxy( name )
  496.  
  497. if ( self.NWVarProxies ) then
  498. local func = self.NWVarProxies[ name ]
  499. if ( isfunction( func ) ) then
  500. return func
  501. end
  502. end
  503.  
  504. return nil
  505.  
  506. end
  507.  
  508. meta.SetNWVarProxy = meta.SetNetworkedVarProxy
  509. meta.GetNWVarProxy = meta.GetNetworkedVarProxy
  510.  
  511. hook.Add( "EntityNetworkedVarChanged", "NetworkedVars", function( ent, name, oldValue, newValue )
  512.  
  513. if ( ent.NWVarProxies ) then
  514. local func = ent.NWVarProxies[ name ]
  515.  
  516. if ( isfunction( func ) ) then
  517. func( ent, name, oldValue, newValue )
  518. end
  519. end
  520.  
  521. end )
  522.  
  523. --
  524. -- Vehicle Extensions
  525. --
  526. local vehicle = FindMetaTable( "Vehicle" )
  527.  
  528. --
  529. -- We steal some DT slots by default for vehicles
  530. -- to control the third person view. You should use
  531. -- these functions if you want to play with them because
  532. -- they might eventually be moved into the engine - so manually
  533. -- editing the DT values will stop working.
  534. --
  535. function vehicle:SetVehicleClass( s )
  536.  
  537. self:SetDTString( 3, s )
  538.  
  539. end
  540.  
  541. function vehicle:GetVehicleClass()
  542.  
  543. return self:GetDTString( 3 )
  544.  
  545. end
  546.  
  547. function vehicle:SetThirdPersonMode( b )
  548.  
  549. self:SetDTBool( 3, b )
  550.  
  551. end
  552.  
  553. function vehicle:GetThirdPersonMode()
  554.  
  555. return self:GetDTBool( 3 )
  556.  
  557. end
  558.  
  559. function vehicle:SetCameraDistance( dist )
  560.  
  561. self:SetDTFloat( 3, dist )
  562.  
  563. end
  564.  
  565. function vehicle:GetCameraDistance()
  566.  
  567. return self:GetDTFloat( 3 )
  568.  
  569. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement