code_gs

GMod Achievement System

May 27th, 2020
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.38 KB | None | 0 0
  1. local curid = 0
  2. local bits = 0
  3. local nettable = {}
  4.  
  5. -- FIXME: Put into separate PR
  6. function math.BitCount( num )
  7.     if ( num == 0 ) then
  8.         return 0
  9.     end
  10.    
  11.     return math.floor( math.log( num, 2 ) ) + 1
  12. end
  13.  
  14. if ( SERVER ) then
  15.     achievements = {}
  16.    
  17.     util.AddNetworkString( "GMod_Achievements" )
  18.     util.AddNetworkString( "GMod_Achievements_Sync" )
  19.     util.AddNetworkString( "GMod_Achievements_New" )
  20.    
  21.    
  22.     -- Shared functions --
  23.    
  24.     function achievements.Register( name, func --[[= nil]], update --[[= true]] )
  25.         -- FIXME: Typecheck func
  26.        
  27.         if ( nettable[ name ] == nil ) then
  28.             nettable[ name ] = curid
  29.  
  30.             if ( func != nil ) then
  31.                 nettable[ curid ] = func
  32.             end
  33.  
  34.             bits = math.BitCount( curid )
  35.             curid = curid + 1
  36.  
  37.             if ( update == nil || update ) then
  38.                 net.Start( "GMod_Achievements_New" )
  39.                     net.WriteString( name )
  40.                 net.Broadcast()
  41.             end
  42.         else
  43.             nettable[ nettable[ name ] ] = func
  44.         end
  45.     end
  46.    
  47.     function achievements.Exists( name )
  48.         return nettable[ name ] != nil
  49.     end
  50.    
  51.     function achievements.GetFunction( name )
  52.         local id = nettable[ name ]
  53.        
  54.         if ( id == nil ) then
  55.             return nil
  56.         end
  57.        
  58.         return nettable[ id ]
  59.     end
  60.    
  61.    
  62.     -- Server functions --
  63.    
  64.     function achievements.Call( name, plys --[[= player.GetAll()]], ... )
  65.         -- FIXME: Typecheck plys
  66.        
  67.         local id = nettable[ name ]
  68.        
  69.         if ( id == nil ) then
  70.             ErrorNoHalt( string.format( "Attempted to call unregistered achievement '%s'", name ) )
  71.             return false
  72.         end
  73.        
  74.         net.Start( "GMod_Achievements" )
  75.             net.WriteUInt( id, bits )
  76.            
  77.             local func = nettable[ id ]
  78.            
  79.             if ( func != nil ) then
  80.                 func( ... )
  81.             end
  82.         if ( plys == nil ) then
  83.             net.Broadcast()
  84.         else
  85.             net.Send( plys )
  86.         end
  87.        
  88.         return true
  89.     end
  90.    
  91.     function achievements.Sync( plys --[[= player.GetAll()]] )
  92.         -- FIXME: Typecheck plys
  93.        
  94.         net.Start( "GMod_Achievements_Sync" )
  95.             net.WriteUInt( curid, 32 )
  96.            
  97.             for id = 0, curid - 1 do
  98.                 net.WriteString( nettable[ id ] )
  99.             end
  100.         if ( plys == nil ) then
  101.             net.Broadcast()
  102.         else
  103.             net.Send( plys )
  104.         end
  105.     end
  106.    
  107.     -- FIXME: https://github.com/Facepunch/garrysmod-requests/issues/718
  108.     hook.Add( "PlayerInitialSpawn", "GMod_Achievements", function( ply )
  109.         local id = "GMod_Achievements_" .. ply:SteamID64()
  110.        
  111.         hook.Add( "SetupMove", id, function( pply, _, cmd )
  112.             if ( !ply:IsValid() ) then
  113.                 hook.Remove( "SetupMove", id )
  114.             elseif ( pply == ply && cmd:IsForced() ) then
  115.                 achievements.Sync( ply )
  116.                 hook.Remove( "SetupMove", id )
  117.             end
  118.         end)
  119.     end )
  120. else
  121.     local funcs = {}
  122.    
  123.    
  124.     -- Shared functions --
  125.    
  126.     function achievements.Register( name, func --[[= nil]] )
  127.         -- FIXME: Typecheck func
  128.        
  129.         funcs[ name ] = func
  130.         local id = nettable[ name ]
  131.        
  132.         if ( id ~= nil ) then
  133.             nettable[ id ] = func
  134.         end
  135.     end
  136.    
  137.     function achievements.Exists( name )
  138.         return nettable[ name ] != nil || funcs[ name ] != nil
  139.     end
  140.    
  141.     function achievements.GetFunction( name )
  142.         return funcs[ name ]
  143.     end
  144.  
  145.    
  146.     -- Client functions --
  147.    
  148.     function achievements.Pooled( name )
  149.         return nettable[ name ] != nil
  150.     end
  151.    
  152.     net.Receive( "GMod_Achievements", function()
  153.         local func = nettable[ net.ReadUInt( bits ) ]
  154.        
  155.         if ( func != nil ) then
  156.             func()
  157.         end
  158.     end )
  159.    
  160.     net.Receive( "GMod_Achievements_Sync", function()
  161.         curid = net.ReadUInt( 32 )
  162.        
  163.         for id = 0, curid - 1 do
  164.             local name = net.ReadString()
  165.             nettable[ name ] = id
  166.             nettable[ id ] = funcs[ name ]
  167.         end
  168.     end )
  169.    
  170.     net.Receive( "GMod_Achievements_New", function()
  171.         bits = math.BitCount( curid )
  172.        
  173.         local name = net.ReadString()
  174.         nettable[ name ] = curid
  175.         nettable[ curid ] = funcs[ name ]
  176.        
  177.         curid = curid + 1
  178.     end )
  179. end
  180.  
  181. achievements.Register( "BalloonPopped", Either( CLIENT, achievements.BalloonPopped, nil ) )
  182. achievements.Register( "EatBall", Either( CLIENT, achievements.EatBall, nil ) )
  183. achievements.Register( "SpawnedNPC", Either( CLIENT, achievements.SpawnedNPC, nil ) )
  184. achievements.Register( "SpawnedProp", Either( CLIENT, achievements.SpawnedProp, nil ) )
  185. achievements.Register( "SpawnedRagdoll", Either( CLIENT, achievements.SpawnedRagdoll, nil ) )
  186.  
  187. achievements.Register( "Remover", Either( CLIENT, function()
  188.     for i = 0, net.ReadUInt( 32 ) do
  189.         achievements.Remover()
  190.     end
  191. end, function( count --[[= 1]] )
  192.     if ( isnumber( count ) ) then
  193.         net.WriteUInt( count, 32 )
  194.     else
  195.         net.WriteUInt( 1, 32 )
  196.     end
  197. end ) )
Add Comment
Please, Sign In to add comment