Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --GarrysMod/garrysmod/lua/entities/nbplayerbase.lua
- AddCSLuaFile()
- ENT.Base = "base_nextbot"
- ENT.Spawnable = true
- function ENT:Initialize()
- self:SetModel( "models/Combine_Soldier.mdl" )
- self.SearchRadius = 5000
- self.LoseTargetDist = 6000
- end
- function ENT:Reload()
- end
- function ENT:SetEnemy( ent )
- self.Enemy = ent
- end
- function ENT:GetEnemy()
- return self.Enemy
- end
- --[[function ENT:HaveEnemy()
- if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then
- if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > 6000 ) then
- return self:FindEnemy()
- elseif ( self:GetEnemy():Health() <= 0 and self:GetEnemy():IsPlayer() ) then
- return self:FindEnemy()
- --Attacking
- elseif ( self:GetRangeTo( self:GetEnemy() ) <= self.PunchDist ) then --If the enemy is close enough, punch them
- self:PunchEnemy( math.random( 10, 20 ) )
- end
- return true
- else
- return self:FindEnemy()
- end
- end]]
- function ENT:HaveEnemy()
- if ( self:GetEnemy() and IsValid( self:GetEnemy() ) ) then
- if ( self:GetRangeTo( self:GetEnemy():GetPos() ) > self.LoseTargetDist ) then
- return self:FindEnemy()
- --if our enemy is too far then chase a new player
- elseif ( self:GetEnemy():Health() <= 0 and self:GetEnemy():IsPlayer() ) then
- return self:FindEnemy()
- --Attacking
- elseif ( self:GetRangeTo( self:GetEnemy() ) <= 1000 ) then --If the enemy is close enough, punch them
- self:FireWeapon()
- end
- return true
- else
- return self:FindEnemy()
- end
- end
- function ENT:Think()
- if !IsValid( self.Weapon ) then
- self:GiveWeapon()
- end
- self:BodyUpdate()
- self:BodyMoveXY()
- end
- function ENT:GiveWeapon()
- local att = "anim_attachment_RH"
- local shootpos = self:GetAttachment(self:LookupAttachment(att))
- local wep = ents.Create("sent_weapon")
- wep:SetOwner(self)
- wep:SetPos(shootpos.Pos)
- --wep:SetAngles(ang)
- wep:Spawn()
- wep:SetModel( "models/weapons/w_shotgun.mdl" )
- wep:SetSolid(SOLID_NONE)
- wep:SetParent(self)
- wep:Fire("setparentattachment", "anim_attachment_RH")
- wep:AddEffects(EF_BONEMERGE)
- wep:SetAngles(self:GetForward():Angle())
- self.Weapon = wep
- end
- function ENT:FireWeapon()
- if !self.Weapon then return end
- local wep = self.Weapon
- local attID = wep:LookupAttachment("muzzle")
- if attID == 0 then attID = 1 end
- local muzzle = wep:GetAttachment(attID)
- local spread = .52
- local numBullets = 6
- local shootPos = muzzle.Pos
- self:EmitSound( "Weapon_Shotgun.Single" )
- local bullet = {}
- bullet.Num = numBullets
- bullet.Src = shootPos
- bullet.Dir = self:GetForward() -- ENT:GetAimVector() equivalent
- bullet.Spread = Vector( spread * 0.1 , spread * 0.1, 0)
- bullet.Tracer = 1
- bullet.TracerName = "Tracer"
- bullet.Force = 50
- bullet.Damage = 6
- bullet.AmmoType = "Pistol"
- self:MuzzleFlash()
- wep:FireBullets(bullet)
- self.loco:FaceTowards( self:GetEnemy():GetPos() )
- self:PlaySequenceAndWait( "shootSGs", 3 )
- if self:GetRangeTo( self:GetEnemy():GetPos() ) <= 1000 then return end
- self:StartActivity( ACT_RUN_AIM_SHOTGUN )
- end
- function ENT:FindEnemy()
- local _ents = ents.FindByClass( "player" )--InSphere( self:GetPos(), 5000 )--self.SearchRadius )
- for k, v in pairs( _ents ) do
- if ( IsValid( v ) and v:IsPlayer() and v:Health() > 0 ) then
- --I know I already stated in haveenemy that we will give up if our enemy is dead but this
- --is so we don't find another one that is dead when we're done
- self:SetEnemy( v )
- return true
- end
- end
- self:SetEnemy( nil )
- return false
- end
- function ENT:RunBehaviour()
- while ( true ) do
- if ( self:HaveEnemy() ) then
- --self.loco:FaceTowards( self:GetEnemy():GetPos() ) -- Face our enemy
- self:StartActivity( ACT_RUN_AIM_SHOTGUN )
- self.loco:SetDesiredSpeed( 200 )
- self.loco:SetAcceleration( 400 )
- self:ChaseEnemy()
- --self.loco:SetAcceleration( 400 )
- self:StartActivity( ACT_IDLE_SHOTGUN_AGITATED )
- else
- self:StartActivity( ACT_RUN_AIM_SHOTGUN )
- self.loco:SetDesiredSpeed( 200 )
- local area = navmesh.Find( self:GetPos(), 1000, 40, 40 )
- local nav = area[math.random( 1, #area )]
- if !IsValid( nav ) then return end
- if nav:IsUnderwater() then return end
- local pos = nav:GetRandomPoint()
- local maxAge = math.Clamp( pos:Distance( self:GetPos() ) / 120, 0.1, 10 )
- self:MoveToPos( pos, { tolerance = 30, maxage = maxAge, lookahead = 10, repath = 2 } )
- self:StartActivity( ACT_RUN_AIM_SHOTGUN )
- end
- end
- end
- function ENT:ChaseEnemy( options )
- local options = options or {}
- local path = Path( "Follow" )
- path:SetMinLookAheadDistance( options.lookahead or 300 )
- path:SetGoalTolerance( options.tolerance or 20 )
- path:Compute( self, self:GetEnemy():GetPos() ) -- Compute the path towards the enemy's position
- if ( !path:IsValid() ) then return "failed" end
- while ( path:IsValid() and self:HaveEnemy() ) do
- if self:GetRangeTo(self:GetEnemy():GetPos()) <= 1000 then break end
- if ( path:GetAge() > 0.1 ) then -- Since we are following the player we have to constantly remake the path
- path:Compute( self, self:GetEnemy():GetPos() )-- Compute the path towards the enemy's position again
- end
- path:Update( self ) -- This function moves the bot along the path
- if ( options.draw ) then path:Draw() end
- -- If we're stuck then call the HandleStuck function and abandon
- if ( self.loco:IsStuck() ) then
- self:HandleStuck()
- return "stuck"
- end
- coroutine.yield()
- end
- return "ok"
- end
- --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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement