Guest User

GMod: Nextbot

a guest
Aug 6th, 2015
53
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --GarrysMod/garrysmod/lua/entities/nbplayerbase.lua
  2.  
  3. AddCSLuaFile()
  4.  
  5. ENT.Base            = "base_nextbot"
  6. ENT.Spawnable       = true
  7.  
  8. function ENT:Initialize()
  9.  
  10.     self:SetModel( "models/Combine_Soldier.mdl" )
  11.  
  12.    
  13.     self.SearchRadius = 5000
  14.    
  15.     self.LoseTargetDist = 6000
  16.  
  17. end
  18.  
  19. function ENT:Reload()
  20.  
  21.  
  22.  
  23. end
  24.  
  25. function ENT:SetEnemy( ent )
  26.  
  27.     self.Enemy = ent
  28.  
  29. end
  30.  
  31. function ENT:GetEnemy()
  32.  
  33.     return self.Enemy
  34.  
  35. end
  36.  
  37. --[[function ENT:HaveEnemy()
  38.  
  39.     if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then
  40.  
  41.         if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > 6000 ) then
  42.  
  43.             return self:FindEnemy()
  44.        
  45.         elseif ( self:GetEnemy():Health() <= 0 and self:GetEnemy():IsPlayer() ) then
  46.        
  47.             return self:FindEnemy()
  48.            
  49.         --Attacking
  50.        
  51.         elseif ( self:GetRangeTo( self:GetEnemy() ) <= self.PunchDist ) then --If the enemy is close enough, punch them
  52.        
  53.             self:PunchEnemy( math.random( 10, 20 ) )
  54.            
  55.         end
  56.        
  57.         return true
  58.        
  59.     else
  60.        
  61.         return self:FindEnemy()
  62.        
  63.     end
  64.    
  65. end]]
  66.  
  67. function ENT:HaveEnemy()
  68.  
  69.     if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then
  70.  
  71.     if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > self.LoseTargetDist ) then
  72.  
  73.             return self:FindEnemy()
  74.            
  75.     --if our enemy is too far then chase a new player
  76.        
  77.         elseif ( self:GetEnemy():Health() <= 0 and self:GetEnemy():IsPlayer() ) then
  78.        
  79.             return self:FindEnemy()
  80.            
  81.         --Attacking
  82.        
  83.         elseif ( self:GetRangeTo( self:GetEnemy() ) <= 1000 ) then --If the enemy is close enough, punch them
  84.        
  85.             self:FireWeapon()
  86.        
  87.         end
  88.        
  89.         return true
  90.        
  91.     else
  92.        
  93.         return self:FindEnemy()
  94.        
  95.     end
  96.    
  97. end
  98.  
  99. function ENT:Think()
  100.  
  101.     if !IsValid( self.Weapon ) then
  102.    
  103.         self:GiveWeapon()
  104.    
  105.     end
  106.  
  107.     self:BodyUpdate()
  108.     self:BodyMoveXY()
  109.  
  110. end
  111.  
  112. function ENT:GiveWeapon()
  113.  
  114.         local att = "anim_attachment_RH"
  115.         local shootpos = self:GetAttachment(self:LookupAttachment(att))
  116.        
  117.         local wep = ents.Create("sent_weapon")
  118.         wep:SetOwner(self)
  119.         wep:SetPos(shootpos.Pos)
  120.        
  121.         --wep:SetAngles(ang)
  122.         wep:Spawn()
  123.        
  124.         wep:SetModel( "models/weapons/w_shotgun.mdl" )
  125.        
  126.         wep:SetSolid(SOLID_NONE)
  127.        
  128.        
  129.         wep:SetParent(self)
  130.  
  131.         wep:Fire("setparentattachment", "anim_attachment_RH")
  132.         wep:AddEffects(EF_BONEMERGE)
  133.         wep:SetAngles(self:GetForward():Angle())
  134.        
  135.         self.Weapon = wep
  136.        
  137. end
  138.  
  139. function ENT:FireWeapon()
  140.  
  141.         if !self.Weapon then return end
  142.  
  143.         local wep = self.Weapon
  144.        
  145.         local attID = wep:LookupAttachment("muzzle")
  146.         if attID == 0 then attID = 1 end
  147.        
  148.         local muzzle = wep:GetAttachment(attID)
  149.         local spread = .52
  150.         local numBullets = 6
  151.        
  152.         local shootPos = muzzle.Pos
  153.         self:EmitSound( "Weapon_Shotgun.Single" )
  154.                
  155.         local bullet = {}
  156.             bullet.Num = numBullets
  157.             bullet.Src = shootPos
  158.             bullet.Dir = self:GetForward() -- ENT:GetAimVector() equivalent
  159.             bullet.Spread = Vector( spread * 0.1 , spread * 0.1, 0)
  160.             bullet.Tracer = 1
  161.             bullet.TracerName    = "Tracer"
  162.             bullet.Force = 50
  163.             bullet.Damage = 6
  164.             bullet.AmmoType = "Pistol"
  165.            
  166.         self:MuzzleFlash()
  167.        
  168.         wep:FireBullets(bullet)
  169.        
  170.         self.loco:FaceTowards( self:GetEnemy():GetPos() )
  171.        
  172.         self:PlaySequenceAndWait( "shootSGs", 3 )
  173.        
  174.         if self:GetRangeTo( self:GetEnemy():GetPos() ) <= 1000 then return end
  175.        
  176.         self:StartActivity( ACT_RUN_AIM_SHOTGUN )
  177.        
  178. end
  179.  
  180. function ENT:FindEnemy()
  181.  
  182.     local _ents = ents.FindByClass( "player" )--InSphere( self:GetPos(), 5000 )--self.SearchRadius )
  183.    
  184.     for k, v in pairs( _ents ) do
  185.    
  186.         if ( IsValid( v ) and v:IsPlayer() and v:Health() > 0 ) then
  187.        
  188.         --I know I already stated in haveenemy that we will give up if our enemy is dead but this
  189.        
  190.         --is so we don't find another one that is dead when we're done
  191.            
  192.             self:SetEnemy( v )
  193.            
  194.             return true
  195.            
  196.         end
  197.        
  198.     end
  199.    
  200.    
  201.     self:SetEnemy( nil )
  202.    
  203.     return false
  204.    
  205. end
  206.  
  207. function ENT:RunBehaviour()
  208.    
  209.     while ( true ) do
  210.        
  211.         if ( self:HaveEnemy() ) then
  212.            
  213.             --self.loco:FaceTowards( self:GetEnemy():GetPos() ) -- Face our enemy
  214.             self:StartActivity( ACT_RUN_AIM_SHOTGUN )
  215.             self.loco:SetDesiredSpeed( 200 )
  216.             self.loco:SetAcceleration( 400 )
  217.             self:ChaseEnemy()
  218.             --self.loco:SetAcceleration( 400 )
  219.             self:StartActivity( ACT_IDLE_SHOTGUN_AGITATED )
  220.            
  221.         else
  222.  
  223.             self:StartActivity( ACT_RUN_AIM_SHOTGUN )
  224.             self.loco:SetDesiredSpeed( 200 )
  225.            
  226.             local area = navmesh.Find( self:GetPos(), 1000, 40, 40 )
  227.            
  228.             local nav = area[math.random( 1, #area )]
  229.    
  230.             if !IsValid( nav ) then return end
  231.             if nav:IsUnderwater() then return end
  232.    
  233.             local pos = nav:GetRandomPoint()
  234.    
  235.             local maxAge = math.Clamp( pos:Distance( self:GetPos() ) / 120, 0.1, 10 )
  236.    
  237.             self:MoveToPos( pos, { tolerance = 30, maxage = maxAge, lookahead = 10, repath = 2 } )
  238.            
  239.             self:StartActivity( ACT_RUN_AIM_SHOTGUN )
  240.            
  241.         end
  242.  
  243.  
  244.     end
  245.  
  246. end
  247.  
  248. function ENT:ChaseEnemy( options )
  249.  
  250.     local options = options or {}
  251.  
  252.     local path = Path( "Follow" )
  253.     path:SetMinLookAheadDistance( options.lookahead or 300 )
  254.     path:SetGoalTolerance( options.tolerance or 20 )
  255.     path:Compute( self, self:GetEnemy():GetPos() )      -- Compute the path towards the enemy's position
  256.  
  257.     if ( !path:IsValid() ) then return "failed" end
  258.  
  259.     while ( path:IsValid() and self:HaveEnemy() ) do
  260.    
  261.         if self:GetRangeTo(self:GetEnemy():GetPos()) <= 1000 then break end
  262.  
  263.         if ( path:GetAge() > 0.1 ) then                 -- Since we are following the player we have to constantly remake the path
  264.             path:Compute( self, self:GetEnemy():GetPos() )-- Compute the path towards the enemy's position again
  265.         end
  266.         path:Update( self )                             -- This function moves the bot along the path
  267.  
  268.         if ( options.draw ) then path:Draw() end
  269.         -- If we're stuck then call the HandleStuck function and abandon
  270.         if ( self.loco:IsStuck() ) then
  271.             self:HandleStuck()
  272.             return "stuck"
  273.         end
  274.  
  275.         coroutine.yield()
  276.  
  277.     end
  278.  
  279.     return "ok"
  280.  
  281. end
  282.  
  283. --This bot will not work because you don't have the "sent_weapon" entity. The code for that one can be found here: http://pastebin.com/khevsgYq
RAW Paste Data